1
0
mirror of https://github.com/Rogiel/l2jserver2 synced 2025-12-10 09:22:49 +00:00

Character calculators

Signed-off-by: Rogiel <rogiel@rogiel.com>
This commit is contained in:
2011-05-23 23:49:19 -03:00
parent 1909bb06cc
commit a1b1211616
206 changed files with 4749 additions and 1170 deletions

View File

@@ -36,7 +36,7 @@ import com.l2jserver.service.game.npc.NPCServiceImpl;
import com.l2jserver.service.game.pathing.MapperPathingService;
import com.l2jserver.service.game.pathing.PathingService;
import com.l2jserver.service.game.scripting.ScriptingService;
import com.l2jserver.service.game.scripting.PreCompiledScriptingService;
import com.l2jserver.service.game.scripting.ScriptingServiceImpl;
import com.l2jserver.service.game.spawn.SpawnService;
import com.l2jserver.service.game.spawn.SpawnServiceImpl;
import com.l2jserver.service.game.template.ScriptTemplateService;
@@ -78,7 +78,7 @@ public class ServiceModule extends AbstractModule {
.in(Scopes.SINGLETON);
bind(NetworkService.class).to(NettyNetworkService.class).in(
Scopes.SINGLETON);
bind(ScriptingService.class).to(PreCompiledScriptingService.class).in(
bind(ScriptingService.class).to(ScriptingServiceImpl.class).in(
Scopes.SINGLETON);
bind(TemplateService.class).to(ScriptTemplateService.class).in(
Scopes.SINGLETON);

View File

@@ -16,17 +16,23 @@
*/
package com.l2jserver.service.database;
import java.util.Iterator;
import com.google.inject.Inject;
import com.l2jserver.model.Model;
import com.l2jserver.model.id.ID;
/**
* Abstract DAO implementations. Store an instance of {@link DatabaseService}.
* Default {@link Iterator} implementation in this class supports
* {@link Iterator#remove()} and will delete the row from the database.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
* @param <T>
* the dao object type
* @param <I>
* the object id type
*/
public abstract class AbstractDAO<T extends Model<?>, I extends ID<?>>
implements DataAccessObject<T, I> {
@@ -53,6 +59,39 @@ public abstract class AbstractDAO<T extends Model<?>, I extends ID<?>>
return false;
}
@Override
public Iterator<T> iterator() {
return new Iterator<T>() {
/**
* The Iterator that will return the ID objects
*/
private final Iterator<I> iterator = AbstractDAO.this.selectIDs()
.iterator();
/**
* The last used ID (will be used to remove the last element)
*/
private I lastID;
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public T next() {
lastID = iterator.next();
if (lastID == null)
return null;
return select(lastID);
}
@Override
public void remove() {
AbstractDAO.this.delete(select(lastID));
}
};
}
/**
* @return the database service
*/

View File

@@ -16,23 +16,32 @@
*/
package com.l2jserver.service.database;
import java.util.Iterator;
import java.util.List;
import com.l2jserver.model.Model;
import com.l2jserver.model.id.ID;
import com.l2jserver.service.cache.IgnoreCaching;
/**
* The DAO interface
* The Data Access Object interface used used to retrieve, save and remove
* objects from the database. The underlying storage engine can be an plain text
* file, SQL Database or an serialized version of the object. This layer will
* abstract the translation of the data and ease the transition from one engine
* to another.
* <p>
* TODO make DAO an {@link Iterable}. So if we want to select all objects we can
* do like this: <code><pre>
* for(final Object o : daoInstance) {
* ...
* }
* </pre></code>
* Every DAO is also an {@link Iterable}. If you wish you can iterate through
* all objects in the database very abstractly. But please note that the default
* {@link Iterator} implementation in {@link AbstractDAO} will load all the
* {@link ID} objects and for every call {@link Iterator#next()}, a new database
* query will be made requesting the given object. In a large dataset, this
* could be a huge performance issue. DAO implementations are encouraged to
* override the iterator implementation with a more specific implementation.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface DataAccessObject<O extends Model<?>, I extends ID<?>> {
public interface DataAccessObject<O extends Model<?>, I extends ID<?>> extends
Iterable<O> {
/**
* Load the instance represented by <tt>id</tt> from the database
*
@@ -41,6 +50,14 @@ public interface DataAccessObject<O extends Model<?>, I extends ID<?>> {
*/
O select(I id);
/**
* Loads an List of all {@link ID}s in the database
*
* @return the list containing all {@link ID} objects
*/
@IgnoreCaching
List<I> selectIDs();
/**
* Save the instance to the database. If a new database entry was created
* returns true.

View File

@@ -41,9 +41,10 @@ import org.slf4j.LoggerFactory;
import com.google.common.base.Preconditions;
import com.google.inject.Inject;
import com.l2jserver.model.id.ObjectID;
import com.l2jserver.model.Model;
import com.l2jserver.model.Model.ObjectState;
import com.l2jserver.model.id.ID;
import com.l2jserver.model.id.object.allocator.IDAllocator;
import com.l2jserver.model.world.WorldObject;
import com.l2jserver.service.AbstractService;
import com.l2jserver.service.AbstractService.Depends;
import com.l2jserver.service.ServiceStartException;
@@ -268,6 +269,11 @@ public class MySQLDatabaseService extends AbstractService implements
final PreparedStatement st = conn.prepareStatement(query());
this.parametize(st, object);
rows += st.executeUpdate();
// update object state
if (object instanceof Model)
((Model<?>) object).setObjectState(ObjectState.STORED);
final Mapper<T> mapper = keyMapper(object);
if (mapper == null)
continue;
@@ -330,8 +336,11 @@ public class MySQLDatabaseService extends AbstractService implements
final ResultSet rs = st.getResultSet();
while (rs.next()) {
final T obj = mapper().map(rs);
if (obj != null)
list.add(obj);
if (obj == null)
continue;
if (obj instanceof Model)
((Model<?>) obj).setObjectState(ObjectState.STORED);
list.add(obj);
}
return list;
}
@@ -385,7 +394,10 @@ public class MySQLDatabaseService extends AbstractService implements
st.execute();
final ResultSet rs = st.getResultSet();
while (rs.next()) {
return mapper().map(rs);
final T object = mapper().map(rs);
if (object instanceof Model)
((Model<?>) object).setObjectState(ObjectState.STORED);
return object;
}
return null;
}
@@ -456,27 +468,30 @@ public class MySQLDatabaseService extends AbstractService implements
* @param <I>
* the id type
*/
public abstract static class CachedMapper<T extends WorldObject, I extends ObjectID<T>>
public abstract static class CachedMapper<T extends Model<?>, I extends ID<?>>
implements Mapper<T> {
/**
* The database service instance
*/
private final MySQLDatabaseService database;
private final Mapper<I> idMapper;
/**
* Creates a new instance
*
* @param database
* the database service
*/
public CachedMapper(MySQLDatabaseService database) {
public CachedMapper(MySQLDatabaseService database, Mapper<I> idMapper) {
this.database = database;
this.idMapper = idMapper;
}
@Override
@SuppressWarnings("unchecked")
public final T map(ResultSet rs) throws SQLException {
final I id = createID(rs);
final I id = idMapper.map(rs);
Preconditions.checkNotNull(id, "id");
if (database.hasCachedObject(id))
@@ -488,16 +503,6 @@ public class MySQLDatabaseService extends AbstractService implements
return object;
}
/**
* Creates an ID for an object
*
* @param rs
* the jdbc result set
* @return the id
* @throws SQLException
*/
protected abstract I createID(ResultSet rs) throws SQLException;
/**
* Maps an uncached object. Once mapping is complete, it will be added
* to the cache.

View File

@@ -31,7 +31,6 @@ import java.util.Set;
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public abstract class ScriptClassLoader extends URLClassLoader {
/**
* Just for compatibility with {@link URLClassLoader}
*

View File

@@ -43,7 +43,7 @@ public interface ScriptCompiler {
* @param files
* list of jar files
*/
void setLibraires(Iterable<File> files);
void setLibraries(Iterable<File> files);
/**
* Compiles single class that is represented as string
@@ -51,10 +51,10 @@ public interface ScriptCompiler {
* @param className
* class name
* @param sourceCode
* class sourse code
* class source code
* @return {@link CompilationResult}
*/
CompilationResult compile(String className, String sourceCode);
CompilationResult compile(String className, byte[] sourceCode);
/**
* Compiles classes that are represented as strings
@@ -67,7 +67,7 @@ public interface ScriptCompiler {
* @throws IllegalArgumentException
* if number of class names != number of sources
*/
CompilationResult compile(String[] className, String[] sourceCode)
CompilationResult compile(String[] className, byte[][] sourceCode)
throws IllegalArgumentException;
/**
@@ -80,7 +80,7 @@ public interface ScriptCompiler {
CompilationResult compile(Iterable<File> compilationUnits);
/**
* Returns array of supported file types. This files will be threated as
* Returns array of supported file types. This files will be treated as
* source files.
*
* @return array of supported file types.

View File

@@ -48,13 +48,13 @@ import com.l2jserver.util.factory.CollectionFactory;
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
@Depends(LoggingService.class)
public class PreCompiledScriptingService extends AbstractService implements
public class ScriptingServiceImpl extends AbstractService implements
ScriptingService {
/**
* Logger for script context
*/
private static final Logger log = LoggerFactory
.getLogger(PreCompiledScriptingService.class);
.getLogger(ScriptingServiceImpl.class);
private final Injector injector;
@@ -64,7 +64,7 @@ public class PreCompiledScriptingService extends AbstractService implements
private final Set<ScriptContext> contexts = CollectionFactory.newSet();
@Inject
public PreCompiledScriptingService(Injector injector) {
public ScriptingServiceImpl(Injector injector) {
this.injector = injector;
}

View File

@@ -14,7 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.game.scripting.impl.javacc;
package com.l2jserver.service.game.scripting.impl;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -58,10 +58,25 @@ public class BinaryClass implements JavaFileObject {
* @param name
* class name
*/
protected BinaryClass(String name) {
public BinaryClass(String name) {
this.name = name;
}
/**
* Constructor that accepts class name as parameter
*
* @param name
* class name
*/
public BinaryClass(String name, byte[] data) {
this.name = name;
try {
this.baos.write(data);
} catch (IOException e) {
throw new RuntimeException("Cannor write class data", e);
}
}
/**
* Throws {@link UnsupportedOperationException}
*

View File

@@ -14,7 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.game.scripting.impl.javacc;
package com.l2jserver.service.game.scripting.impl;
import java.util.Locale;
@@ -26,7 +26,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This class is simple compiler error listener that forwards errors to log4j
* This class is simple compiler error listener that forwards errors to slf4j
* logger
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
@@ -40,7 +40,7 @@ public class ErrorListener implements DiagnosticListener<JavaFileObject> {
.getLogger(ErrorListener.class);
/**
* Reports compilation errors to log4j
* Reports compilation errors to slf4j
*
* @param diagnostic
* compiler errors

View File

@@ -14,7 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.game.scripting.impl.javacc;
package com.l2jserver.service.game.scripting.impl;
import java.net.URI;
@@ -26,11 +26,11 @@ import javax.tools.SimpleJavaFileObject;
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class JavaSourceFromString extends SimpleJavaFileObject {
public class JavaSourceFromByteArray extends SimpleJavaFileObject {
/**
* Source code of the class
*/
private final String code;
private final byte[] code;
/**
* Creates new object that contains sources of java class
@@ -40,13 +40,28 @@ public class JavaSourceFromString extends SimpleJavaFileObject {
* @param code
* source code of class
*/
public JavaSourceFromString(String className, String code) {
public JavaSourceFromByteArray(String className, byte[] code) {
super(URI.create("string:///" + className.replace('.', '/')
+ JavaFileObject.Kind.SOURCE.extension),
JavaFileObject.Kind.SOURCE);
this.code = code;
}
/**
* Creates new object that contains sources of java class
*
* @param className
* class name of class
* @param code
* source code of class
*/
public JavaSourceFromByteArray(String className, byte[] code,
JavaFileObject.Kind kind) {
super(URI.create("string:///" + className.replace('.', '/')
+ JavaFileObject.Kind.SOURCE.extension), kind);
this.code = code;
}
/**
* Returns class source code
*
@@ -56,6 +71,6 @@ public class JavaSourceFromString extends SimpleJavaFileObject {
*/
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return code;
return new String(code);
}
}

View File

@@ -14,7 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.game.scripting.impl.javacc;
package com.l2jserver.service.game.scripting.impl;
import java.io.File;
import java.io.IOException;
@@ -30,7 +30,6 @@ import org.apache.commons.io.FileUtils;
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class JavaSourceFromFile extends SimpleJavaFileObject {
/**
* Construct a JavaFileObject of the given kind and with the given File.
*

View File

@@ -143,7 +143,7 @@ public class ScriptContextImpl implements ScriptContext {
.getCompilationResult().getClassLoader());
}
scriptCompiler.setLibraires(libraries);
scriptCompiler.setLibraries(libraries);
compilationResult = scriptCompiler.compile(files);
getClassListener().postLoad(compilationResult.getCompiledClasses());

View File

@@ -0,0 +1,137 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.game.scripting.impl.compiled;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import org.apache.commons.io.FileUtils;
import com.l2jserver.service.game.scripting.ScriptClassLoader;
import com.l2jserver.util.factory.CollectionFactory;
/**
* This classloader is used to load script classes. <br>
* <br>
* Due to JavaCompiler limitations we have to keep list of available classes
* here.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class PrecompiledScriptClassLoader extends ScriptClassLoader {
/**
* Map of all loaded classes
*/
private final Map<String, Class<?>> classes = CollectionFactory.newMap();
/**
* Creates new ScriptClassLoader with given ClassFileManger
*/
PrecompiledScriptClassLoader(final File root) {
super(new URL[] {});
}
/**
* Creates new ScriptClassLoader with given ClassFileManger and another
* classLoader as parent
*
* @param parent
* parent classLoader
*/
PrecompiledScriptClassLoader(ClassLoader parent) {
super(new URL[] {}, parent);
}
/**
* AddsLibrary jar
*
* @param file
* jar file to add
* @throws IOException
*/
@Override
public void addLibrary(File file) throws IOException {
}
/**
* Loads class from library, parent or compiled
*
* @param name
* class to load
* @param file
* the class file
* @return loaded class
* @throws ClassNotFoundException
* if class not found
* @throws IOException
*/
public Class<?> loadClass(File file) throws ClassNotFoundException,
IOException {
byte[] b = FileUtils.readFileToByteArray(file);
Class<?> c = super.defineClass(null, b, 0, b.length);
classes.put(c.getName(), c);
return c;
}
@Override
public synchronized Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException {
final File file = new File("target/templates");
final File classFile = new File(file, name.replaceAll("\\.", "/")
+ ".class");
System.out.println(name + " -> " + classFile);
if (!classFile.exists()) {
System.out.println("super");
return super.loadClass(name, resolve);
} else if (classes.containsKey(name)) {
return classes.get(name);
} else {
try {
byte[] b = FileUtils.readFileToByteArray(classFile);
System.out.println("Defining...");
Class<?> c = super.defineClass(null, b, 0, b.length);
classes.put(c.getName(), c);
System.out.println(c.getName());
return c;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
/**
* {@inheritDoc}
*/
@Override
public Set<String> getLibraryClasses() {
return Collections.emptySet();
}
/**
* {@inheritDoc}
*/
@Override
public Set<String> getCompiledClasses() {
return Collections.unmodifiableSet(classes.keySet());
}
}

View File

@@ -0,0 +1,93 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.game.scripting.impl.compiled;
import java.io.File;
import java.io.IOException;
import java.util.List;
import com.l2jserver.service.game.scripting.CompilationResult;
import com.l2jserver.service.game.scripting.ScriptClassLoader;
import com.l2jserver.service.game.scripting.ScriptCompiler;
import com.l2jserver.util.factory.CollectionFactory;
/**
* Wrapper for JavaCompiler api
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class PrecompiledScriptCompiler implements ScriptCompiler {
/**
* Parent classloader that has to be used for this compiler
*/
protected ScriptClassLoader parentClassLoader;
public PrecompiledScriptCompiler() {
}
@Override
public void setParentClassLoader(ScriptClassLoader classLoader) {
parentClassLoader = classLoader;
}
@Override
public void setLibraries(Iterable<File> files) {
// do nothing
}
@Override
public CompilationResult compile(String className, byte[] sourceCode) {
throw new UnsupportedOperationException(
"This compiler cannot compile from source");
}
@Override
public CompilationResult compile(String[] className, byte[][] sourceCode)
throws IllegalArgumentException {
throw new UnsupportedOperationException(
"This compiler cannot compile from source");
}
@Override
public CompilationResult compile(Iterable<File> compilationUnits) {
final PrecompiledScriptClassLoader cl = new PrecompiledScriptClassLoader(
this.getClass().getClassLoader());
final List<Class<?>> classes = CollectionFactory.newList();
for (final File file : compilationUnits) {
try {
classes.add(cl.loadClass(file));
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return new CompilationResult(classes.toArray(new Class<?>[classes
.size()]), cl);
}
/**
* Only class files are supported by this compiler
*
* @return "class";
*/
@Override
public String[] getSupportedFileTypes() {
return new String[] { "class" };
}
}

View File

@@ -34,6 +34,7 @@ import javax.tools.JavaFileObject.Kind;
import javax.tools.StandardLocation;
import com.l2jserver.service.game.scripting.ScriptClassLoader;
import com.l2jserver.service.game.scripting.impl.BinaryClass;
import com.l2jserver.util.factory.CollectionFactory;
/**

View File

@@ -35,6 +35,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.l2jserver.service.game.scripting.ScriptClassLoader;
import com.l2jserver.service.game.scripting.impl.BinaryClass;
import com.l2jserver.util.ClassUtils;
import com.l2jserver.util.factory.CollectionFactory;

View File

@@ -33,6 +33,9 @@ import org.slf4j.LoggerFactory;
import com.l2jserver.service.game.scripting.CompilationResult;
import com.l2jserver.service.game.scripting.ScriptClassLoader;
import com.l2jserver.service.game.scripting.ScriptCompiler;
import com.l2jserver.service.game.scripting.impl.ErrorListener;
import com.l2jserver.service.game.scripting.impl.JavaSourceFromByteArray;
import com.l2jserver.service.game.scripting.impl.JavaSourceFromFile;
import com.l2jserver.util.factory.CollectionFactory;
/**
@@ -41,7 +44,6 @@ import com.l2jserver.util.factory.CollectionFactory;
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class ScriptCompilerImpl implements ScriptCompiler {
/**
* Logger for this class
*/
@@ -99,7 +101,7 @@ public class ScriptCompilerImpl implements ScriptCompiler {
* list of jar files
*/
@Override
public void setLibraires(Iterable<File> files) {
public void setLibraries(Iterable<File> files) {
libraries = files;
}
@@ -115,8 +117,8 @@ public class ScriptCompilerImpl implements ScriptCompiler {
* if compilation failed with errros
*/
@Override
public CompilationResult compile(String className, String sourceCode) {
return compile(new String[] { className }, new String[] { sourceCode });
public CompilationResult compile(String className, byte[] sourceCode) {
return compile(new String[] { className }, new byte[][] { sourceCode });
}
/**
@@ -134,7 +136,7 @@ public class ScriptCompilerImpl implements ScriptCompiler {
* if compilation failed with errros
*/
@Override
public CompilationResult compile(String[] classNames, String[] sourceCode)
public CompilationResult compile(String[] classNames, byte[][] sourceCode)
throws IllegalArgumentException {
if (classNames.length != sourceCode.length) {
@@ -145,7 +147,7 @@ public class ScriptCompilerImpl implements ScriptCompiler {
List<JavaFileObject> compilationUnits = CollectionFactory.newList();
for (int i = 0; i < classNames.length; i++) {
JavaFileObject compilationUnit = new JavaSourceFromString(
JavaFileObject compilationUnit = new JavaSourceFromByteArray(
classNames[i], sourceCode[i]);
compilationUnits.add(compilationUnit);
}
@@ -212,7 +214,7 @@ public class ScriptCompilerImpl implements ScriptCompiler {
}
/**
* Reolves list of classes by their names
* Resolves list of classes by their names
*
* @param classNames
* names of the classes

View File

@@ -22,6 +22,8 @@ import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import com.l2jserver.service.game.scripting.impl.BinaryClass;
/**
* This class represents URL Connection that is used to "connect" to scripts
* binary data that was loaded by specified {@link ScriptCompilerImpl}.<br>

View File

@@ -82,7 +82,8 @@ public class CachedWorldIDService extends AbstractService implements
@Inject
public CachedWorldIDService(CacheService cacheService,
IDAllocator allocator, CharacterDAO characterDao, ItemDAO itemDao, NPCDAO npcDao) {
IDAllocator allocator, CharacterDAO characterDao, ItemDAO itemDao,
NPCDAO npcDao) {
this.cacheService = cacheService;
this.allocator = allocator;
this.characterDao = characterDao;
@@ -103,9 +104,9 @@ public class CachedWorldIDService extends AbstractService implements
@Override
public void load() {
load(characterDao.listIDs());
load(itemDao.listIDs());
//load(npcDao.listIDs());
load(characterDao.selectIDs());
load(itemDao.selectIDs());
load(npcDao.selectIDs());
loaded = true;
}