mirror of
https://github.com/Rogiel/l2jserver2
synced 2026-02-02 16:02:47 +00:00
Greatly improves source code documentation
This commit is contained in:
@@ -16,7 +16,6 @@
|
||||
*/
|
||||
package com.l2jserver.model;
|
||||
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -72,9 +71,9 @@ public abstract class AbstractModel<T extends ID<?>> implements Model<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this object desire to {@link ObjectDesire#UPDATE}. If the desire is
|
||||
* {@link ObjectDesire#INSERT} or {@link ObjectDesire#DELETE} the desire
|
||||
* will not be changed.
|
||||
* Set this object desire to {@link Model.ObjectDesire#UPDATE}. If the
|
||||
* desire is {@link Model.ObjectDesire#INSERT} or
|
||||
* {@link Model.ObjectDesire#DELETE} the desire will not be changed.
|
||||
*/
|
||||
protected void desireUpdate() {
|
||||
if (this.desire != ObjectDesire.INSERT
|
||||
@@ -85,8 +84,8 @@ public abstract class AbstractModel<T extends ID<?>> implements Model<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this object desire to {@link ObjectDesire#INSERT}. If the desire is
|
||||
* {@link ObjectDesire#DELETE} the desire will not be changed.
|
||||
* Set this object desire to {@link Model.ObjectDesire#INSERT}. If the desire is
|
||||
* {@link Model.ObjectDesire#DELETE} the desire will not be changed.
|
||||
*/
|
||||
protected void desireInsert() {
|
||||
if (this.desire != ObjectDesire.DELETE) {
|
||||
|
||||
@@ -45,10 +45,10 @@ public abstract class AbstractDAO<T extends Model<?>, I extends ID<?>>
|
||||
*/
|
||||
protected final DatabaseService database;
|
||||
|
||||
@Inject
|
||||
/**
|
||||
* The ThreadService used to execute operations asynchronously.
|
||||
*/
|
||||
@Inject
|
||||
protected ThreadService threadService;
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,6 +3,12 @@ package com.l2jserver.service.database;
|
||||
import com.l2jserver.model.Model;
|
||||
import com.l2jserver.model.id.ID;
|
||||
|
||||
/**
|
||||
* The {@link DAOResolver} resolves the {@link DataAccessObject} that provides
|
||||
* database operations for an given {@link Model} instance
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface DAOResolver {
|
||||
/**
|
||||
* Returns the {@link DataAccessObject} used to retrieve and save objects of
|
||||
|
||||
@@ -20,8 +20,14 @@ package com.l2jserver.service.database;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class DatabaseException extends RuntimeException {
|
||||
/**
|
||||
* The Java Serialization API ID
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Creates a new instane
|
||||
*/
|
||||
public DatabaseException() {
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -20,8 +20,14 @@ package com.l2jserver.service.database;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class DatabaseMappingException extends DatabaseException {
|
||||
/**
|
||||
* The Java Serialization API ID
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Creates a new instane
|
||||
*/
|
||||
public DatabaseMappingException() {
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -31,7 +31,13 @@ import com.mysema.query.types.Path;
|
||||
*/
|
||||
public class SelectPrimaryKeyMapper<R, I extends ID<? super R>, E extends RelationalPathBase<R>>
|
||||
implements SelectMapper<I, R, I, E> {
|
||||
/**
|
||||
* The primary key mapper
|
||||
*/
|
||||
private final PrimaryKeyMapper<I, R> mapper;
|
||||
/**
|
||||
* The primary key path
|
||||
*/
|
||||
private final Path<R> path;
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,6 +30,15 @@ import com.l2jserver.util.factory.CollectionFactory;
|
||||
*
|
||||
*/
|
||||
public class QueryFactory {
|
||||
/**
|
||||
* Creates an <code>CREATE TABLE</code> query from an {@link Table} object
|
||||
*
|
||||
* @param table
|
||||
* the table object
|
||||
* @param template
|
||||
* the query template
|
||||
* @return the <code>CREATE TABLE</code> query as string
|
||||
*/
|
||||
public static String createTableQuery(Table table, QueryTemplate template) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append(template.getCreateTable())
|
||||
@@ -59,6 +68,18 @@ public class QueryFactory {
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an <code>ALTER TABLE</code> query from the difference between two
|
||||
* {@link Table} objects
|
||||
*
|
||||
* @param expected
|
||||
* the desired table model
|
||||
* @param current
|
||||
* the current table model
|
||||
* @param template
|
||||
* the query template
|
||||
* @return the <code>ALTER TABLE</code> query as string
|
||||
*/
|
||||
public static String alterTableQueryDelta(Table expected, Table current,
|
||||
QueryTemplate template) {
|
||||
// detect missing columns
|
||||
@@ -108,6 +129,20 @@ public class QueryFactory {
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an <code>ALTER TABLE</code> query from the difference between two
|
||||
* {@link Table} objects.
|
||||
* <p>
|
||||
* This method does not delete any column.
|
||||
*
|
||||
* @param expected
|
||||
* the desired table model
|
||||
* @param current
|
||||
* the current table model
|
||||
* @param template
|
||||
* the query template
|
||||
* @return the <code>ALTER TABLE</code> query as string
|
||||
*/
|
||||
public static String alterTableQueryUpdate(Table expected, Table current,
|
||||
QueryTemplate template) {
|
||||
// detect missing columns
|
||||
@@ -144,6 +179,19 @@ public class QueryFactory {
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an <code>ALTER TABLE</code> query from the difference between two
|
||||
* {@link Table} objects. Note that this method will only add missing
|
||||
* columns, but won't update their types.
|
||||
*
|
||||
* @param expected
|
||||
* the desired table model
|
||||
* @param current
|
||||
* the current table model
|
||||
* @param template
|
||||
* the query template
|
||||
* @return the <code>ALTER TABLE</code> query as string
|
||||
*/
|
||||
public static String alterTableQueryMissing(Table expected, Table current,
|
||||
QueryTemplate template) {
|
||||
// detect missing columns
|
||||
@@ -172,6 +220,16 @@ public class QueryFactory {
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param builder
|
||||
* the {@link StringBuilder}
|
||||
* @param template
|
||||
* the query template
|
||||
* @param column
|
||||
* the column
|
||||
* @param alter
|
||||
* whether it is an alter table or create table
|
||||
*/
|
||||
private static void createColumnDefinition(StringBuilder builder,
|
||||
QueryTemplate template, Column column, boolean alter) {
|
||||
builder.append(template.quoteIdentifier(column.getName())).append(" ");
|
||||
@@ -215,6 +273,16 @@ public class QueryFactory {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param builder
|
||||
* the {@link StringBuilder}
|
||||
* @param template
|
||||
* the query template
|
||||
* @param table
|
||||
* the table
|
||||
* @param pk
|
||||
* the primary key
|
||||
*/
|
||||
private static void generatePrimaryKeyDefinition(StringBuilder builder,
|
||||
QueryTemplate template, Table table, PrimaryKey pk) {
|
||||
builder.append("CONSTRAINT ")
|
||||
@@ -227,6 +295,14 @@ public class QueryFactory {
|
||||
// .append(")");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param builder
|
||||
* the {@link StringBuilder}
|
||||
* @param template
|
||||
* the query template
|
||||
* @param fk
|
||||
* the foreign key
|
||||
*/
|
||||
private static void generateForeignKeyDefinition(StringBuilder builder,
|
||||
QueryTemplate template, ForeignKey fk) {
|
||||
builder.append("CONSTRAINT ")
|
||||
|
||||
@@ -44,39 +44,85 @@ public abstract class QueryTemplate extends SQLTemplates {
|
||||
// String getColumnDefinition(String name, ColumnType type, int size,
|
||||
// boolean nullable);
|
||||
|
||||
/**
|
||||
* @param type
|
||||
* the column type
|
||||
* @return the database specific type
|
||||
*/
|
||||
public abstract String getDatabaseType(ColumnType type);
|
||||
|
||||
/**
|
||||
* @param type
|
||||
* the column type
|
||||
* @return true if the database requires an size parameter for the column
|
||||
* type
|
||||
*/
|
||||
public abstract boolean getTypeSizeRequirement(ColumnType type);
|
||||
|
||||
/**
|
||||
* @return true if the database supports enums
|
||||
*/
|
||||
public abstract boolean supportsEnum();
|
||||
|
||||
/**
|
||||
* @return true if the database supports auto increment
|
||||
*/
|
||||
public abstract boolean supportsAutoIncrement();
|
||||
|
||||
/**
|
||||
* @return true if the database supports foreign keys
|
||||
*/
|
||||
public abstract boolean supportsForeignKeys();
|
||||
|
||||
/**
|
||||
* @return true if the database supports changing column types
|
||||
*/
|
||||
public abstract boolean supportsColumnChangeTypes();
|
||||
|
||||
/**
|
||||
* @return true if the database supports renaming columns
|
||||
*/
|
||||
public abstract boolean supportsColumnRename();
|
||||
|
||||
/**
|
||||
* @return true if the database supports altering tables
|
||||
*/
|
||||
public abstract boolean supportsAlterTable();
|
||||
|
||||
/**
|
||||
* @param defaultValue
|
||||
* the value
|
||||
* @return the quoted value
|
||||
*/
|
||||
public String quoteValue(String defaultValue) {
|
||||
return new StringBuilder("'").append(defaultValue).append("'")
|
||||
.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the <code>ALTER TABLE</code> statement
|
||||
*/
|
||||
public String getAlterTable() {
|
||||
return "alter table ";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the <code>ADD COLUMN</code> statement
|
||||
*/
|
||||
public String getAddColumn() {
|
||||
return "add column ";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the <code>DROP COLUMN</code> statement
|
||||
*/
|
||||
public String getDropColumn() {
|
||||
return "drop column ";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the <code>ALTER COLUMN</code> statement
|
||||
*/
|
||||
public String getAlterColumn() {
|
||||
return "alter column ";
|
||||
}
|
||||
|
||||
@@ -131,6 +131,13 @@ public class TableFactory {
|
||||
return fks;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tablePath
|
||||
* the query entity
|
||||
* @param columns
|
||||
* the columns
|
||||
* @return the primary key object
|
||||
*/
|
||||
private static PrimaryKey createPK(RelationalPath<?> tablePath,
|
||||
Map<String, Column> columns) {
|
||||
return new PrimaryKey(columns.get(tablePath.getPrimaryKey()
|
||||
@@ -138,6 +145,13 @@ public class TableFactory {
|
||||
.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tablePath
|
||||
* the query entity
|
||||
* @param path
|
||||
* the path
|
||||
* @return the column object
|
||||
*/
|
||||
private static Column createColumn(RelationalPath<?> tablePath, Path<?> path) {
|
||||
final String columnName = path.getMetadata().getExpression().toString();
|
||||
final ColumnType columnType = getColumnType(path.getType());
|
||||
@@ -197,6 +211,11 @@ public class TableFactory {
|
||||
hasDefaultValue, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param type
|
||||
* the java type
|
||||
* @return the database column type
|
||||
*/
|
||||
private static ColumnType getColumnType(Class<?> type) {
|
||||
if (ClassUtils.isSubclass(type, String.class))
|
||||
return ColumnType.STRING;
|
||||
@@ -215,6 +234,11 @@ public class TableFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param jdbcType
|
||||
* the JDBC type
|
||||
* @return the database column type
|
||||
*/
|
||||
private static ColumnType getColumnType(int jdbcType) {
|
||||
switch (jdbcType) {
|
||||
case Types.INTEGER:
|
||||
|
||||
@@ -33,5 +33,8 @@ import com.mysema.query.sql.RelationalPath;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface ColumnDefault {
|
||||
/**
|
||||
* @return the default column value
|
||||
*/
|
||||
String value() default "NULL";
|
||||
}
|
||||
|
||||
@@ -33,5 +33,8 @@ import com.mysema.query.sql.RelationalPath;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface ColumnSize {
|
||||
/**
|
||||
* @return the maximum column value
|
||||
*/
|
||||
int value();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.l2jserver.service.database.ddl.struct;
|
||||
|
||||
import java.sql.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jserver.util.factory.CollectionFactory;
|
||||
@@ -24,18 +25,67 @@ import com.l2jserver.util.factory.CollectionFactory;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class Column {
|
||||
/**
|
||||
* The column name
|
||||
*/
|
||||
private final String name;
|
||||
/**
|
||||
* The column type
|
||||
*/
|
||||
private final ColumnType type;
|
||||
|
||||
/**
|
||||
* Define the supported column types
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
*/
|
||||
public enum ColumnType {
|
||||
STRING, ENUM, INTEGER, DOUBLE, TIMESTAMP;
|
||||
/**
|
||||
* {@link String} type
|
||||
*/
|
||||
STRING,
|
||||
/**
|
||||
* {@link Enum} type
|
||||
*/
|
||||
ENUM,
|
||||
/**
|
||||
* {@link Integer} type
|
||||
*/
|
||||
INTEGER,
|
||||
/**
|
||||
* {@link Double} type
|
||||
*/
|
||||
DOUBLE,
|
||||
/**
|
||||
* {@link Date} type
|
||||
*/
|
||||
TIMESTAMP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the column is nullable or not
|
||||
*/
|
||||
private boolean nullable = true;
|
||||
/**
|
||||
* The maximum size of the column
|
||||
*/
|
||||
private int size = 0;
|
||||
/**
|
||||
* Whether the column has a default value
|
||||
*/
|
||||
private boolean hasDefaultValue = false;
|
||||
/**
|
||||
* The column default value
|
||||
*/
|
||||
private String defaultValue = null;
|
||||
/**
|
||||
* The enum values
|
||||
*/
|
||||
private List<String> enumValues = CollectionFactory.newList();
|
||||
/**
|
||||
* Whether the column requires ID generation
|
||||
*/
|
||||
private boolean autoIncrement;
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,7 +24,13 @@ import java.util.List;
|
||||
*
|
||||
*/
|
||||
public class ForeignKey {
|
||||
/**
|
||||
* The key name
|
||||
*/
|
||||
private final String name;
|
||||
/**
|
||||
* The key columns
|
||||
*/
|
||||
private final List<Column> columns;
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,6 +20,9 @@ package com.l2jserver.service.database.ddl.struct;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class PrimaryKey {
|
||||
/**
|
||||
* The primary key column
|
||||
*/
|
||||
private final Column column;
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,12 +28,30 @@ import com.l2jserver.util.factory.CollectionFactory;
|
||||
*
|
||||
*/
|
||||
public class Table {
|
||||
/**
|
||||
* The table name
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* The columns
|
||||
*/
|
||||
private final Map<String, Column> columns = CollectionFactory.newMap();
|
||||
/**
|
||||
* The primary key
|
||||
*/
|
||||
private final PrimaryKey primaryKey;
|
||||
/**
|
||||
* The foreign keys
|
||||
*/
|
||||
private final List<ForeignKey> foreignKeys = CollectionFactory.newList();
|
||||
|
||||
/**
|
||||
* @param name the table name
|
||||
* @param columns the column
|
||||
* @param primaryKey the primary key
|
||||
* @param foreignKeys the foreign keys
|
||||
*/
|
||||
public Table(String name, Map<String, Column> columns,
|
||||
PrimaryKey primaryKey, List<ForeignKey> foreignKeys) {
|
||||
this.name = name;
|
||||
@@ -43,6 +61,10 @@ public class Table {
|
||||
this.foreignKeys.addAll(foreignKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name the table name
|
||||
* @param primaryKey the primary key
|
||||
*/
|
||||
public Table(String name, PrimaryKey primaryKey) {
|
||||
this.name = name;
|
||||
this.primaryKey = primaryKey;
|
||||
@@ -81,6 +103,10 @@ public class Table {
|
||||
return column;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name the column name
|
||||
* @return the column represented by <code>name</code>
|
||||
*/
|
||||
public Column getColumn(String name) {
|
||||
for (final Column column : columns.values()) {
|
||||
if (name.equals(column.getName()))
|
||||
|
||||
@@ -27,12 +27,24 @@ import com.mysema.query.types.Ops;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class DerbyTemplate extends QueryTemplate {
|
||||
/**
|
||||
* The limit offset template string
|
||||
*/
|
||||
private String limitOffsetTemplate = "\noffset {1s} rows fetch next {0s} rows only";
|
||||
|
||||
/**
|
||||
* The limit template string
|
||||
*/
|
||||
private String limitTemplate = "\nfetch first {0s} rows only";
|
||||
|
||||
/**
|
||||
* The offset template string
|
||||
*/
|
||||
private String offsetTemplate = "\noffset {0s} rows";
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*/
|
||||
public DerbyTemplate() {
|
||||
super("\"", '\\', true);
|
||||
addClass2TypeMappings("smallint", Byte.class);
|
||||
|
||||
@@ -24,6 +24,9 @@ import com.mysema.query.types.Ops;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class H2Template extends QueryTemplate {
|
||||
/**
|
||||
* Creates a new instance
|
||||
*/
|
||||
public H2Template() {
|
||||
super("\"", '\\', true);
|
||||
setNativeMerge(true);
|
||||
|
||||
@@ -26,6 +26,9 @@ import com.mysema.query.types.Ops;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class MySQLTemplate extends QueryTemplate {
|
||||
/**
|
||||
* Creates a new instance
|
||||
*/
|
||||
public MySQLTemplate() {
|
||||
super("`", '\\', true);
|
||||
addClass2TypeMappings("bool", Boolean.class);
|
||||
|
||||
@@ -496,7 +496,24 @@ public abstract class AbstractOrientDatabaseService extends AbstractService
|
||||
R query(ODatabaseDocumentTx database, DatabaseService service);
|
||||
}
|
||||
|
||||
public static abstract class AbstractQuery<R> implements Query<R> {
|
||||
/**
|
||||
* An base abstract query. For internal use only.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
* @param <R>
|
||||
* the query return type
|
||||
*/
|
||||
private static abstract class AbstractQuery<R> implements Query<R> {
|
||||
/**
|
||||
* Tries to update the object desire if it currently is equal to
|
||||
* <code>expected</code>
|
||||
*
|
||||
* @param object
|
||||
* the object to update desire
|
||||
* @param expected
|
||||
* the expected desire
|
||||
*/
|
||||
protected void updateDesire(Object object, ObjectDesire expected) {
|
||||
if (object instanceof Model) {
|
||||
if (((Model<?>) object).getObjectDesire() == expected) {
|
||||
@@ -505,18 +522,53 @@ public abstract class AbstractOrientDatabaseService extends AbstractService
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parameter name for the given <code>path</code>
|
||||
*
|
||||
* @param path
|
||||
* the path
|
||||
* @return the parameter name
|
||||
*/
|
||||
protected String name(Path<?> path) {
|
||||
return path.getMetadata().getExpression().toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An query implementation designed to insert new objects into the database.
|
||||
* Optionally, it can use an pseudo primary key generator that maps the
|
||||
* OrientDB document id as the generated ID.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
* @param <O>
|
||||
* the object type used in this query
|
||||
* @param <RI>
|
||||
* the raw ID type
|
||||
* @param <I>
|
||||
* the ID type
|
||||
* @param <E>
|
||||
* the entity type
|
||||
*/
|
||||
public static class InsertQuery<O, RI, I extends ID<? super RI>, E extends RelationalPathBase<?>>
|
||||
extends AbstractQuery<Integer> {
|
||||
/**
|
||||
* The row mapper
|
||||
*/
|
||||
private final InsertMapper<O, RI, I, E> mapper;
|
||||
/**
|
||||
* The query object iterator
|
||||
*/
|
||||
private final Iterator<O> iterator;
|
||||
/**
|
||||
* The query primary key column. Only set if want auto generated IDs
|
||||
*/
|
||||
private final Path<RI> primaryKey;
|
||||
|
||||
protected final E e;
|
||||
/**
|
||||
* The query entity
|
||||
*/
|
||||
protected final E entity;
|
||||
|
||||
/**
|
||||
* @param entity
|
||||
@@ -533,7 +585,7 @@ public abstract class AbstractOrientDatabaseService extends AbstractService
|
||||
Path<RI> primaryKey, Iterator<O> iterator) {
|
||||
this.iterator = iterator;
|
||||
this.mapper = mapper;
|
||||
this.e = entity;
|
||||
this.entity = entity;
|
||||
this.primaryKey = primaryKey;
|
||||
}
|
||||
|
||||
@@ -589,9 +641,9 @@ public abstract class AbstractOrientDatabaseService extends AbstractService
|
||||
final DocumentDatabaseRow row = new DocumentDatabaseRow();
|
||||
while (iterator.hasNext()) {
|
||||
final O object = iterator.next();
|
||||
row.setDocument(new ODocument(database, e.getTableName()));
|
||||
row.setDocument(new ODocument(database, entity.getTableName()));
|
||||
|
||||
mapper.insert(e, object, row);
|
||||
mapper.insert(entity, object, row);
|
||||
|
||||
row.getDocument().save();
|
||||
if (primaryKey != null && object instanceof Model) {
|
||||
@@ -614,11 +666,30 @@ public abstract class AbstractOrientDatabaseService extends AbstractService
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An query implementation designed to update objects in the database
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
* @param <O>
|
||||
* the query object type
|
||||
* @param <E>
|
||||
* the query entity type
|
||||
*/
|
||||
public static abstract class UpdateQuery<O, E extends RelationalPathBase<?>>
|
||||
extends AbstractQuery<Integer> {
|
||||
/**
|
||||
* The row mapper
|
||||
*/
|
||||
private final UpdateMapper<O, E> mapper;
|
||||
/**
|
||||
* The object iterator for this query
|
||||
*/
|
||||
private final Iterator<O> iterator;
|
||||
protected final E e;
|
||||
/**
|
||||
* The query entity
|
||||
*/
|
||||
protected final E entity;
|
||||
|
||||
/**
|
||||
* @param entity
|
||||
@@ -632,7 +703,7 @@ public abstract class AbstractOrientDatabaseService extends AbstractService
|
||||
Iterator<O> iterator) {
|
||||
this.iterator = iterator;
|
||||
this.mapper = mapper;
|
||||
this.e = entity;
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -658,7 +729,7 @@ public abstract class AbstractOrientDatabaseService extends AbstractService
|
||||
|
||||
List<ODocument> documents = database
|
||||
.query(new ONativeSynchQuery<OQueryContextNative>(
|
||||
database, e.getTableName(),
|
||||
database, entity.getTableName(),
|
||||
new OQueryContextNative()) {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -670,7 +741,7 @@ public abstract class AbstractOrientDatabaseService extends AbstractService
|
||||
if (documents.size() < 1)
|
||||
continue;
|
||||
row.setDocument(documents.get(0));
|
||||
mapper.update(e, object, row);
|
||||
mapper.update(entity, object, row);
|
||||
|
||||
row.getDocument().save();
|
||||
rows++;
|
||||
@@ -680,14 +751,40 @@ public abstract class AbstractOrientDatabaseService extends AbstractService
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the OrientDB document filtering. If all results are wanted,
|
||||
* <code>null</code> should be returned.
|
||||
*
|
||||
* @param record
|
||||
* the document record
|
||||
* @param o
|
||||
* the object instance
|
||||
* @return the record instance or <code>null</code>
|
||||
*/
|
||||
protected abstract OQueryContextNative query(
|
||||
OQueryContextNative record, O o);
|
||||
}
|
||||
|
||||
/**
|
||||
* An query implementation designed for deleting objects in the database.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
* @param <O>
|
||||
* the query object type
|
||||
* @param <E>
|
||||
* the query entity type
|
||||
*/
|
||||
public static abstract class DeleteQuery<O, E extends RelationalPathBase<?>>
|
||||
extends AbstractQuery<Integer> {
|
||||
/**
|
||||
* The object iterator for this query
|
||||
*/
|
||||
private final Iterator<O> iterator;
|
||||
protected final E e;
|
||||
/**
|
||||
* This query entity
|
||||
*/
|
||||
protected final E entity;
|
||||
|
||||
/**
|
||||
* @param entity
|
||||
@@ -697,7 +794,7 @@ public abstract class AbstractOrientDatabaseService extends AbstractService
|
||||
*/
|
||||
public DeleteQuery(E entity, Iterator<O> iterator) {
|
||||
this.iterator = iterator;
|
||||
this.e = entity;
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -720,7 +817,7 @@ public abstract class AbstractOrientDatabaseService extends AbstractService
|
||||
|
||||
List<ODocument> documents = database
|
||||
.query(new ONativeSynchQuery<OQueryContextNative>(
|
||||
database, e.getTableName(),
|
||||
database, entity.getTableName(),
|
||||
new OQueryContextNative()) {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -739,13 +836,46 @@ public abstract class AbstractOrientDatabaseService extends AbstractService
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the OrientDB document filtering. If all results are wanted,
|
||||
* <code>null</code> should be returned.
|
||||
*
|
||||
* @param record
|
||||
* the document record
|
||||
* @param o
|
||||
* the object instance
|
||||
* @return the record instance or <code>null</code>
|
||||
*/
|
||||
protected abstract OQueryContextNative query(
|
||||
OQueryContextNative record, O o);
|
||||
}
|
||||
|
||||
public static abstract class AbstractSelectQuery<R, O, RI, I extends ID<? super RI>, E extends RelationalPathBase<RI>>
|
||||
/**
|
||||
* Abstract query implementation designed for selecting database objects.
|
||||
* Internal use only.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
* @param <R>
|
||||
* the query return type
|
||||
* @param <O>
|
||||
* the query object type
|
||||
* @param <RI>
|
||||
* the raw ID type
|
||||
* @param <I>
|
||||
* the ID type
|
||||
* @param <E>
|
||||
* the query entity type
|
||||
*/
|
||||
private static abstract class AbstractSelectQuery<R, O, RI, I extends ID<? super RI>, E extends RelationalPathBase<RI>>
|
||||
extends AbstractQuery<R> {
|
||||
/**
|
||||
* This query entity type
|
||||
*/
|
||||
protected final E entity;
|
||||
/**
|
||||
* The row mapper
|
||||
*/
|
||||
protected final SelectMapper<O, RI, I, E> mapper;
|
||||
|
||||
/**
|
||||
@@ -778,12 +908,41 @@ public abstract class AbstractOrientDatabaseService extends AbstractService
|
||||
return perform(documents, service);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the OrientDB document filtering. If all results are wanted,
|
||||
* <code>null</code> should be returned.
|
||||
*
|
||||
* @param record
|
||||
* the document record
|
||||
* @param e
|
||||
* the query entity
|
||||
* @return the record instance or <code>null</code>
|
||||
*/
|
||||
protected abstract OQueryContextNative query(
|
||||
OQueryContextNative record, E e);
|
||||
|
||||
/**
|
||||
* Effectively performs the query executing and mapping process
|
||||
*
|
||||
* @param documents
|
||||
* the list of documens returned
|
||||
* @param service
|
||||
* the database service
|
||||
* @return the query result, returned directly to the user
|
||||
*/
|
||||
protected abstract R perform(List<ODocument> documents,
|
||||
DatabaseService service);
|
||||
|
||||
/**
|
||||
* Checks if the object is on the cache. Returns it if available,
|
||||
* <code>null</code> otherwise.
|
||||
*
|
||||
* @param row
|
||||
* the row
|
||||
* @param database
|
||||
* the database service
|
||||
* @return the object on cache, if exists.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected O lookupCache(DatabaseRow row, DatabaseService database) {
|
||||
final I id = mapper.getPrimaryKeyMapper().createID(
|
||||
@@ -797,6 +956,14 @@ public abstract class AbstractOrientDatabaseService extends AbstractService
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the cache instance
|
||||
*
|
||||
* @param instance
|
||||
* the object instance
|
||||
* @param database
|
||||
* the database service
|
||||
*/
|
||||
protected void updateCache(O instance, DatabaseService database) {
|
||||
if (instance == null)
|
||||
return;
|
||||
@@ -806,6 +973,21 @@ public abstract class AbstractOrientDatabaseService extends AbstractService
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An query implementation designed for selecting a single object in the
|
||||
* database
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
* @param <O>
|
||||
* the object type
|
||||
* @param <RI>
|
||||
* the raw ID type
|
||||
* @param <I>
|
||||
* the ID type
|
||||
* @param <E>
|
||||
* the query entity type
|
||||
*/
|
||||
public static abstract class SelectSingleQuery<O, RI, I extends ID<? super RI>, E extends RelationalPathBase<RI>>
|
||||
extends AbstractSelectQuery<O, O, RI, I, E> {
|
||||
/**
|
||||
@@ -838,6 +1020,21 @@ public abstract class AbstractOrientDatabaseService extends AbstractService
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An query implementation designed for selecting several objects in the
|
||||
* database
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
* @param <O>
|
||||
* the object type
|
||||
* @param <RI>
|
||||
* the raw ID type
|
||||
* @param <I>
|
||||
* the ID type
|
||||
* @param <E>
|
||||
* the query entity type
|
||||
*/
|
||||
public static abstract class SelectListQuery<O, RI, I extends ID<? super RI>, E extends RelationalPathBase<RI>>
|
||||
extends AbstractSelectQuery<List<O>, O, RI, I, E> {
|
||||
/**
|
||||
|
||||
@@ -26,6 +26,9 @@ import com.orientechnologies.orient.core.record.impl.ODocument;
|
||||
*
|
||||
*/
|
||||
public class DocumentDatabaseRow implements DatabaseRow, WritableDatabaseRow {
|
||||
/**
|
||||
* The OrientDB {@link ODocument} instance
|
||||
*/
|
||||
private ODocument document;
|
||||
|
||||
/**
|
||||
@@ -36,6 +39,9 @@ public class DocumentDatabaseRow implements DatabaseRow, WritableDatabaseRow {
|
||||
this.document = document;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*/
|
||||
public DocumentDatabaseRow() {
|
||||
}
|
||||
|
||||
|
||||
@@ -649,7 +649,24 @@ public abstract class AbstractSQLDatabaseService extends AbstractService
|
||||
DatabaseService database);
|
||||
}
|
||||
|
||||
/**
|
||||
* An base abstract query. For internal use only.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
* @param <R>
|
||||
* the query return type
|
||||
*/
|
||||
public static abstract class AbstractQuery<R> implements Query<R> {
|
||||
/**
|
||||
* Tries to update the object desire if it currently is equal to
|
||||
* <code>expected</code>
|
||||
*
|
||||
* @param object
|
||||
* the object to update desire
|
||||
* @param expected
|
||||
* the expected desire
|
||||
*/
|
||||
protected void updateDesire(Object object, ObjectDesire expected) {
|
||||
if (object instanceof Model) {
|
||||
if (((Model<?>) object).getObjectDesire() == expected) {
|
||||
@@ -659,13 +676,39 @@ public abstract class AbstractSQLDatabaseService extends AbstractService
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An query implementation designed to insert new objects into the database.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
* @param <O>
|
||||
* the object type used in this query
|
||||
* @param <RI>
|
||||
* the raw ID type
|
||||
* @param <I>
|
||||
* the ID type
|
||||
* @param <E>
|
||||
* the entity type
|
||||
*/
|
||||
public static class InsertQuery<O, RI, I extends ID<? super RI>, E extends RelationalPathBase<?>>
|
||||
extends AbstractQuery<Integer> {
|
||||
/**
|
||||
* The row mapper
|
||||
*/
|
||||
private final InsertMapper<O, RI, I, E> mapper;
|
||||
/**
|
||||
* The query object iterator
|
||||
*/
|
||||
private final Iterator<O> iterator;
|
||||
/**
|
||||
* The query primary key column. Only set if want auto generated IDs
|
||||
*/
|
||||
private final Path<RI> primaryKey;
|
||||
|
||||
protected final E e;
|
||||
/**
|
||||
* The query entity
|
||||
*/
|
||||
protected final E entity;
|
||||
|
||||
/**
|
||||
* @param entity
|
||||
@@ -682,7 +725,7 @@ public abstract class AbstractSQLDatabaseService extends AbstractService
|
||||
Path<RI> primaryKey, Iterator<O> iterator) {
|
||||
this.iterator = iterator;
|
||||
this.mapper = mapper;
|
||||
this.e = entity;
|
||||
this.entity = entity;
|
||||
this.primaryKey = primaryKey;
|
||||
}
|
||||
|
||||
@@ -739,8 +782,8 @@ public abstract class AbstractSQLDatabaseService extends AbstractService
|
||||
while (iterator.hasNext()) {
|
||||
final O object = iterator.next();
|
||||
final SQLInsertWritableDatabaseRow row = new SQLInsertWritableDatabaseRow(
|
||||
factory.insert(e));
|
||||
mapper.insert(e, object, row);
|
||||
factory.insert(entity));
|
||||
mapper.insert(entity, object, row);
|
||||
|
||||
if (primaryKey == null) {
|
||||
row.getClause().execute();
|
||||
@@ -759,11 +802,30 @@ public abstract class AbstractSQLDatabaseService extends AbstractService
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An query implementation designed to update objects in the database
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
* @param <O>
|
||||
* the query object type
|
||||
* @param <E>
|
||||
* the query entity type
|
||||
*/
|
||||
public static abstract class UpdateQuery<O, E extends RelationalPathBase<?>>
|
||||
extends AbstractQuery<Integer> {
|
||||
/**
|
||||
* The row mapper
|
||||
*/
|
||||
private final UpdateMapper<O, E> mapper;
|
||||
/**
|
||||
* The object iterator for this query
|
||||
*/
|
||||
private final Iterator<O> iterator;
|
||||
protected final E e;
|
||||
/**
|
||||
* The query entity
|
||||
*/
|
||||
protected final E entity;
|
||||
|
||||
/**
|
||||
* @param entity
|
||||
@@ -777,7 +839,7 @@ public abstract class AbstractSQLDatabaseService extends AbstractService
|
||||
Iterator<O> iterator) {
|
||||
this.iterator = iterator;
|
||||
this.mapper = mapper;
|
||||
this.e = entity;
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -801,10 +863,10 @@ public abstract class AbstractSQLDatabaseService extends AbstractService
|
||||
while (iterator.hasNext()) {
|
||||
final O object = iterator.next();
|
||||
final SQLUpdateWritableDatabaseRow row = new SQLUpdateWritableDatabaseRow(
|
||||
factory.update(e));
|
||||
factory.update(entity));
|
||||
// maps query to the values
|
||||
query(row.getClause(), object);
|
||||
mapper.update(e, object, row);
|
||||
mapper.update(entity, object, row);
|
||||
|
||||
rows += row.getClause().execute();
|
||||
|
||||
@@ -813,13 +875,37 @@ public abstract class AbstractSQLDatabaseService extends AbstractService
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the query filtering
|
||||
*
|
||||
* @param q
|
||||
* the query clause
|
||||
* @param o
|
||||
* the object
|
||||
*/
|
||||
protected abstract void query(SQLUpdateClause q, O o);
|
||||
}
|
||||
|
||||
/**
|
||||
* An query implementation designed for deleting objects in the database.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
* @param <O>
|
||||
* the query object type
|
||||
* @param <E>
|
||||
* the query entity type
|
||||
*/
|
||||
public static abstract class DeleteQuery<O, E extends RelationalPathBase<?>>
|
||||
extends AbstractQuery<Integer> {
|
||||
/**
|
||||
* The object iterator for this query
|
||||
*/
|
||||
private final Iterator<O> iterator;
|
||||
protected final E e;
|
||||
/**
|
||||
* This query entity
|
||||
*/
|
||||
protected final E entity;
|
||||
|
||||
/**
|
||||
* @param entity
|
||||
@@ -829,7 +915,7 @@ public abstract class AbstractSQLDatabaseService extends AbstractService
|
||||
*/
|
||||
public DeleteQuery(E entity, Iterator<O> iterator) {
|
||||
this.iterator = iterator;
|
||||
this.e = entity;
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -850,7 +936,7 @@ public abstract class AbstractSQLDatabaseService extends AbstractService
|
||||
int rows = 0;
|
||||
while (iterator.hasNext()) {
|
||||
final O object = iterator.next();
|
||||
final SQLDeleteClause delete = factory.delete(e);
|
||||
final SQLDeleteClause delete = factory.delete(entity);
|
||||
// maps query to the values
|
||||
query(delete, object);
|
||||
|
||||
@@ -861,12 +947,43 @@ public abstract class AbstractSQLDatabaseService extends AbstractService
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the query filtering
|
||||
*
|
||||
* @param q
|
||||
* the query clause
|
||||
* @param o
|
||||
* the object
|
||||
*/
|
||||
protected abstract void query(SQLDeleteClause q, O o);
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract query implementation designed for selecting database objects.
|
||||
* Internal use only.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
* @param <R>
|
||||
* the query return type
|
||||
* @param <O>
|
||||
* the query object type
|
||||
* @param <RI>
|
||||
* the raw ID type
|
||||
* @param <I>
|
||||
* the ID type
|
||||
* @param <E>
|
||||
* the query entity type
|
||||
*/
|
||||
public static abstract class AbstractSelectQuery<R, O, RI, I extends ID<? super RI>, E extends RelationalPathBase<RI>>
|
||||
extends AbstractQuery<R> {
|
||||
/**
|
||||
* This query entity type
|
||||
*/
|
||||
protected final E entity;
|
||||
/**
|
||||
* The row mapper
|
||||
*/
|
||||
protected final SelectMapper<O, RI, I, E> mapper;
|
||||
|
||||
/**
|
||||
@@ -891,11 +1008,39 @@ public abstract class AbstractSQLDatabaseService extends AbstractService
|
||||
return perform(select, database);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the query filtering
|
||||
*
|
||||
* @param q
|
||||
* the query clause
|
||||
* @param e
|
||||
* the query entity
|
||||
*/
|
||||
protected abstract void query(AbstractSQLQuery<?> q, E e);
|
||||
|
||||
/**
|
||||
* Effectively performs the query executing and mapping process
|
||||
*
|
||||
* @param select
|
||||
* the query clause ready to be executed (can be modified if
|
||||
* needed)
|
||||
* @param database
|
||||
* the database service
|
||||
* @return the query result, returned directly to the user
|
||||
*/
|
||||
protected abstract R perform(AbstractSQLQuery<?> select,
|
||||
DatabaseService database);
|
||||
|
||||
/**
|
||||
* Checks if the object is on the cache. Returns it if available,
|
||||
* <code>null</code> otherwise.
|
||||
*
|
||||
* @param row
|
||||
* the row
|
||||
* @param database
|
||||
* the database service
|
||||
* @return the object on cache, if exists.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected O lookupCache(DatabaseRow row, DatabaseService database) {
|
||||
final I id = mapper.getPrimaryKeyMapper().createID(
|
||||
@@ -909,6 +1054,14 @@ public abstract class AbstractSQLDatabaseService extends AbstractService
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the cache instance
|
||||
*
|
||||
* @param instance
|
||||
* the object instance
|
||||
* @param database
|
||||
* the database service
|
||||
*/
|
||||
protected void updateCache(O instance, DatabaseService database) {
|
||||
if (instance == null)
|
||||
return;
|
||||
@@ -918,6 +1071,21 @@ public abstract class AbstractSQLDatabaseService extends AbstractService
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An query implementation designed for selecting a single object in the
|
||||
* database
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
* @param <O>
|
||||
* the object type
|
||||
* @param <RI>
|
||||
* the raw ID type
|
||||
* @param <I>
|
||||
* the ID type
|
||||
* @param <E>
|
||||
* the query entity type
|
||||
*/
|
||||
public static abstract class SelectSingleQuery<O, RI, I extends ID<? super RI>, E extends RelationalPathBase<RI>>
|
||||
extends AbstractSelectQuery<O, O, RI, I, E> {
|
||||
/**
|
||||
@@ -950,6 +1118,21 @@ public abstract class AbstractSQLDatabaseService extends AbstractService
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An query implementation designed for selecting several objects in the
|
||||
* database
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
* @param <O>
|
||||
* the object type
|
||||
* @param <RI>
|
||||
* the raw ID type
|
||||
* @param <I>
|
||||
* the ID type
|
||||
* @param <E>
|
||||
* the query entity type
|
||||
*/
|
||||
public static abstract class SelectListQuery<O, RI, I extends ID<? super RI>, E extends RelationalPathBase<RI>>
|
||||
extends AbstractSelectQuery<List<O>, O, RI, I, E> {
|
||||
/**
|
||||
|
||||
@@ -38,18 +38,25 @@ import com.mysema.query.sql.types.Type;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class DerbyDatabaseEngine implements DatabaseEngine {
|
||||
/**
|
||||
* The {@link DerbyTemplate} instance
|
||||
*/
|
||||
private final DerbyTemplate template = new DerbyTemplate();
|
||||
/**
|
||||
* The querydsl configuration
|
||||
*/
|
||||
private final Configuration configuration = new Configuration(template);
|
||||
|
||||
@Override
|
||||
public SQLQueryFactory<? extends AbstractSQLQuery<?>, ?, ?, ?, ?, ?> createSQLQueryFactory(
|
||||
final Connection conn) {
|
||||
return new SQLQueryFactoryImpl(configuration, new Provider<Connection>() {
|
||||
@Override
|
||||
public Connection get() {
|
||||
return conn;
|
||||
}
|
||||
});
|
||||
return new SQLQueryFactoryImpl(configuration,
|
||||
new Provider<Connection>() {
|
||||
@Override
|
||||
public Connection get() {
|
||||
return conn;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -37,7 +37,13 @@ import com.mysema.query.sql.types.Type;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class H2DatabaseEngine implements DatabaseEngine {
|
||||
/**
|
||||
* The {@link H2Template} instance
|
||||
*/
|
||||
private final H2Template template = new H2Template();
|
||||
/**
|
||||
* The querydsl configuration
|
||||
*/
|
||||
private final Configuration configuration = new Configuration(template);
|
||||
|
||||
@Override
|
||||
|
||||
@@ -36,7 +36,13 @@ import com.mysema.query.sql.types.Type;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class MySQLDatabaseEngine implements DatabaseEngine {
|
||||
/**
|
||||
* The {@link MySQLTemplate} instance
|
||||
*/
|
||||
private final QueryTemplate template = new MySQLTemplate();
|
||||
/**
|
||||
* The querydsl configuration
|
||||
*/
|
||||
private final Configuration configuration = new Configuration(template);
|
||||
|
||||
@Override
|
||||
|
||||
@@ -27,10 +27,18 @@ import com.mysema.query.types.Path;
|
||||
*
|
||||
*/
|
||||
public class SQLDatabaseRow implements DatabaseRow {
|
||||
/**
|
||||
* The query entity
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private final RelationalPathBase<?> entity;
|
||||
/**
|
||||
* The cached list of paths
|
||||
*/
|
||||
private final List<Path<?>> paths;
|
||||
|
||||
/**
|
||||
* The database data row
|
||||
*/
|
||||
private Object[] row;
|
||||
|
||||
/**
|
||||
@@ -66,10 +74,19 @@ public class SQLDatabaseRow implements DatabaseRow {
|
||||
return row[indexOf(path)] == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param path
|
||||
* the path
|
||||
* @return the index of <code>path</code>
|
||||
*/
|
||||
private int indexOf(Path<?> path) {
|
||||
return paths.indexOf(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param row
|
||||
* the new row data
|
||||
*/
|
||||
public void setRow(Object[] row) {
|
||||
this.row = row;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,17 @@ import com.l2jserver.util.factory.CollectionFactory;
|
||||
*
|
||||
*/
|
||||
public class ArrayUtils {
|
||||
/**
|
||||
* Copy an entire array except objects in <code>except</code> array.
|
||||
*
|
||||
* @param type
|
||||
* the array type
|
||||
* @param array
|
||||
* the source array
|
||||
* @param except
|
||||
* the objects to not be copied
|
||||
* @return the copied array
|
||||
*/
|
||||
@SafeVarargs
|
||||
public final static <T> T[] copyArrayExcept(Class<T[]> type, T[] array,
|
||||
T... except) {
|
||||
|
||||
@@ -197,6 +197,11 @@ public class CSVUtils {
|
||||
return process(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param map
|
||||
* the CSV row mapped into an {@link Map}
|
||||
* @return the row processed object
|
||||
*/
|
||||
public abstract R process(Map<String, String> map);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,8 +21,14 @@ package com.l2jserver.util.transformer;
|
||||
*
|
||||
*/
|
||||
public class TransformException extends RuntimeException {
|
||||
/**
|
||||
* The Java Serialization API ID
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Creates a new instane
|
||||
*/
|
||||
public TransformException() {
|
||||
}
|
||||
|
||||
|
||||
@@ -26,14 +26,28 @@ import com.l2jserver.model.id.object.allocator.BitSetIDAllocator;
|
||||
import com.l2jserver.model.id.object.allocator.IDAllocator;
|
||||
import com.l2jserver.model.id.object.allocator.IDAllocatorException;
|
||||
|
||||
/**
|
||||
* Tests for {@link BitSetIDAllocator}
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class BitSetIDAllocatorTest {
|
||||
/**
|
||||
* The allocator
|
||||
*/
|
||||
private final BitSetIDAllocator allocator = new BitSetIDAllocator();
|
||||
|
||||
/**
|
||||
* Preparation for tests
|
||||
*/
|
||||
@Before
|
||||
public void tearUp() {
|
||||
allocator.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test id allocation
|
||||
*/
|
||||
@Test
|
||||
public void testAllocate() {
|
||||
final int id1 = allocator.allocate();
|
||||
@@ -43,6 +57,9 @@ public class BitSetIDAllocatorTest {
|
||||
assertEquals(IDAllocator.FIRST_ID + 1, id2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test restoring ID allocation
|
||||
*/
|
||||
@Test
|
||||
public void testAllocateRestore() {
|
||||
final int id1 = IDAllocator.FIRST_ID;
|
||||
@@ -57,6 +74,9 @@ public class BitSetIDAllocatorTest {
|
||||
assertFalse(id2 == id3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests allocation of several ids
|
||||
*/
|
||||
@Test
|
||||
public void testAllocateMany() {
|
||||
for (int i = 0; i < 100 * 1000; i++) {
|
||||
@@ -65,12 +85,18 @@ public class BitSetIDAllocatorTest {
|
||||
assertEquals(100000, allocator.getAllocatedIDs());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests allocation of an used id
|
||||
*/
|
||||
@Test(expected = IDAllocatorException.class)
|
||||
public void testAllocateAlreadyAllocated() {
|
||||
final int id1 = allocator.allocate();
|
||||
allocator.allocate(id1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests id release
|
||||
*/
|
||||
@Test
|
||||
public void testRelease() {
|
||||
final int id = allocator.allocate();
|
||||
@@ -78,6 +104,9 @@ public class BitSetIDAllocatorTest {
|
||||
assertEquals(0, allocator.getAllocatedIDs());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests releasing unallocated id
|
||||
*/
|
||||
@Test(expected = IDAllocatorException.class)
|
||||
public void testReleaseUnalloc() {
|
||||
allocator.release(IDAllocator.FIRST_ID);
|
||||
|
||||
@@ -25,14 +25,30 @@ import org.junit.Test;
|
||||
|
||||
import com.l2jserver.service.ServiceStartException;
|
||||
|
||||
/**
|
||||
* Tests for {@link EhCacheService}
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class SimpleCacheServiceTest {
|
||||
/**
|
||||
* The cache service
|
||||
*/
|
||||
private final EhCacheService cacheService = new EhCacheService();
|
||||
|
||||
/**
|
||||
* Prepation for tests
|
||||
*
|
||||
* @throws ServiceStartException
|
||||
*/
|
||||
@Before
|
||||
public void tearUp() throws ServiceStartException {
|
||||
cacheService.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test proxy cache without arguments
|
||||
*/
|
||||
@Test
|
||||
public void testNoArgs() {
|
||||
final TestCacheable cached = cacheService.decorate(TestCacheable.class,
|
||||
@@ -42,6 +58,9 @@ public class SimpleCacheServiceTest {
|
||||
Assert.assertEquals(output1, output2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test proxy cache with same arguments
|
||||
*/
|
||||
@Test
|
||||
public void testSameArgs() {
|
||||
final TestCacheable cached = cacheService.decorate(TestCacheable.class,
|
||||
@@ -51,6 +70,9 @@ public class SimpleCacheServiceTest {
|
||||
Assert.assertEquals(output1, output2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test proxy cache with different arguments
|
||||
*/
|
||||
@Test
|
||||
public void testDifferentArgs() {
|
||||
final TestCacheable cached = cacheService.decorate(TestCacheable.class,
|
||||
@@ -60,6 +82,9 @@ public class SimpleCacheServiceTest {
|
||||
Assert.assertFalse(output1 == output2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test proxy cache with ignore caching
|
||||
*/
|
||||
@Test
|
||||
public void testIgnoreCaching() {
|
||||
final TestCacheable cached = cacheService.decorate(TestCacheable.class,
|
||||
@@ -69,16 +94,41 @@ public class SimpleCacheServiceTest {
|
||||
Assert.assertFalse(output1 == output2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple cache interface
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
*/
|
||||
public interface TestCacheable extends Cacheable {
|
||||
/**
|
||||
* @return a random number
|
||||
*/
|
||||
public int random();
|
||||
|
||||
/**
|
||||
* @param arg
|
||||
* any argument
|
||||
* @return an random number
|
||||
*/
|
||||
public int random(int arg);
|
||||
|
||||
/**
|
||||
* @return an random number
|
||||
*/
|
||||
@IgnoreCaching
|
||||
public int notCached();
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple {@link TestCacheable} implementation
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public static class TestCacheableInstance implements TestCacheable {
|
||||
/**
|
||||
* Random number generator
|
||||
*/
|
||||
private final Random random = new Random();
|
||||
|
||||
@Override
|
||||
|
||||
@@ -27,8 +27,9 @@ import com.l2jserver.service.ServiceStartException;
|
||||
import com.l2jserver.service.configuration.XMLConfigurationService.ConfigurationXPath;
|
||||
|
||||
/**
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
* Tests for {@link XMLConfigurationService}
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class XMLConfigurationServiceTest {
|
||||
/**
|
||||
@@ -36,6 +37,11 @@ public class XMLConfigurationServiceTest {
|
||||
*/
|
||||
private TestConfig config;
|
||||
|
||||
/**
|
||||
* Preparation for tests
|
||||
*
|
||||
* @throws ServiceStartException
|
||||
*/
|
||||
@Before
|
||||
public void tearUp() throws ServiceStartException {
|
||||
final XMLConfigurationService service = new XMLConfigurationService(
|
||||
@@ -44,27 +50,52 @@ public class XMLConfigurationServiceTest {
|
||||
config = service.get(TestConfig.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test config string
|
||||
*
|
||||
* @throws ServiceStartException
|
||||
*/
|
||||
@Test
|
||||
public void testString() throws ServiceStartException {
|
||||
Assert.assertEquals("test", config.getTestString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test default value
|
||||
*
|
||||
* @throws ServiceStartException
|
||||
*/
|
||||
@Test
|
||||
public void testDefaultValue() throws ServiceStartException {
|
||||
Assert.assertEquals("default", config.getDefaultTestString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test integer
|
||||
*
|
||||
* @throws ServiceStartException
|
||||
*/
|
||||
@Test
|
||||
public void testInteger() throws ServiceStartException {
|
||||
Assert.assertEquals(256, config.getTestInteger());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test setter
|
||||
*
|
||||
* @throws ServiceStartException
|
||||
*/
|
||||
@Test
|
||||
public void testSetter() throws ServiceStartException {
|
||||
config.setTestString("new-value");
|
||||
Assert.assertEquals("new-value", config.getTestString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test null setter
|
||||
*
|
||||
* @throws ServiceStartException
|
||||
*/
|
||||
@Test
|
||||
public void testNullSetter() throws ServiceStartException {
|
||||
config.setTestString(null);
|
||||
@@ -77,22 +108,39 @@ public class XMLConfigurationServiceTest {
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface TestConfig extends Configuration {
|
||||
/**
|
||||
* @return an configuration string
|
||||
*/
|
||||
@ConfigurationPropertyGetter(defaultValue = "test-default")
|
||||
@ConfigurationXPath("/configuration/test/testvalue")
|
||||
String getTestString();
|
||||
|
||||
/**
|
||||
* @param value
|
||||
* any string
|
||||
*/
|
||||
@ConfigurationPropertySetter
|
||||
@ConfigurationXPath("/configuration/test/testvalue")
|
||||
void setTestString(String value);
|
||||
|
||||
/**
|
||||
* @return an configuration string
|
||||
*/
|
||||
@ConfigurationPropertyGetter(defaultValue = "default")
|
||||
@ConfigurationXPath("/configuration/test/nonexistentkey")
|
||||
String getDefaultTestString();
|
||||
|
||||
/**
|
||||
* @return an configuration integer
|
||||
*/
|
||||
@ConfigurationPropertyGetter(defaultValue = "0")
|
||||
@ConfigurationXPath("/configuration/test/integer")
|
||||
int getTestInteger();
|
||||
|
||||
/**
|
||||
* @param n
|
||||
* any integer
|
||||
*/
|
||||
@ConfigurationPropertySetter
|
||||
@ConfigurationXPath("/configuration/test/integer")
|
||||
void setTestInteger(Integer n);
|
||||
|
||||
@@ -23,10 +23,14 @@ import junit.framework.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
* Tests for {@link ArrayUtils}
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class ArrayUtilsTest extends ArrayUtils {
|
||||
/**
|
||||
* Test for {@link ArrayUtils#copyArrayExcept(Class, Object[], Object...)}
|
||||
*/
|
||||
@Test
|
||||
public void testCopyArrayExcept() {
|
||||
final TestClass objA = new TestClass("a");
|
||||
@@ -34,17 +38,26 @@ public class ArrayUtilsTest extends ArrayUtils {
|
||||
final TestClass objC = new TestClass("c");
|
||||
|
||||
TestClass[] arr = new TestClass[] { objA, objB, objC };
|
||||
TestClass[] selected = ArrayUtils.copyArrayExcept(TestClass[].class,
|
||||
arr, objB);
|
||||
TestClass[] selected = copyArrayExcept(TestClass[].class, arr, objB);
|
||||
|
||||
System.out.println(Arrays.toString(selected));
|
||||
Assert.assertTrue(Arrays.equals(new TestClass[] { objA, objC },
|
||||
selected));
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple test class
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
private static class TestClass {
|
||||
/**
|
||||
* The name
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* @param string the name
|
||||
*/
|
||||
public TestClass(String string) {
|
||||
this.name = string;
|
||||
}
|
||||
|
||||
@@ -41,6 +41,9 @@ import com.l2jserver.service.network.keygen.BlowfishKeygenService;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class L2JGameServerMain {
|
||||
/**
|
||||
* List of start services
|
||||
*/
|
||||
public static final Class<?>[][] SERVICES = {
|
||||
// core services
|
||||
{ CacheService.class, ConfigurationService.class,
|
||||
|
||||
@@ -65,6 +65,9 @@ public class CM_CHAR_ACTION extends AbstractClientPacket {
|
||||
* The object id
|
||||
*/
|
||||
private int objectId;
|
||||
/**
|
||||
* The action origin
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private Coordinate origin;
|
||||
/**
|
||||
@@ -72,6 +75,11 @@ public class CM_CHAR_ACTION extends AbstractClientPacket {
|
||||
*/
|
||||
private CharacterAction action;
|
||||
|
||||
/**
|
||||
* The character action type
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public enum CharacterAction {
|
||||
/**
|
||||
* If the player has clicked with the left mouse button.
|
||||
@@ -82,12 +90,24 @@ public class CM_CHAR_ACTION extends AbstractClientPacket {
|
||||
*/
|
||||
RIGHT_CLICK(1);
|
||||
|
||||
/**
|
||||
* The action id
|
||||
*/
|
||||
public final int id;
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* the action id
|
||||
*/
|
||||
CharacterAction(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* the action id
|
||||
* @return the {@link CharacterAction} represented by <code>id</code>
|
||||
*/
|
||||
public static CharacterAction fromID(int id) {
|
||||
for (final CharacterAction action : values())
|
||||
if (action.id == id)
|
||||
@@ -96,6 +116,11 @@ public class CM_CHAR_ACTION extends AbstractClientPacket {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param idResolver the id resolver
|
||||
* @param npcService the npc service
|
||||
* @param itemService the item service
|
||||
*/
|
||||
@Inject
|
||||
public CM_CHAR_ACTION(ObjectIDResolver idResolver, NPCService npcService,
|
||||
ItemService itemService) {
|
||||
@@ -119,8 +144,8 @@ public class CM_CHAR_ACTION extends AbstractClientPacket {
|
||||
final NPC npc = ((NPCID) id).getObject();
|
||||
try {
|
||||
npcService.action(npc, conn.getCharacter(), action);
|
||||
} catch(NPCControllerException e) {
|
||||
if(e.getSystemMessage() != null)
|
||||
} catch (NPCControllerException e) {
|
||||
if (e.getSystemMessage() != null)
|
||||
conn.sendSystemMessage(e.getSystemMessage());
|
||||
conn.sendActionFailed();
|
||||
} catch (ActionServiceException | CannotSetTargetServiceException e) {
|
||||
|
||||
@@ -41,6 +41,9 @@ public class CM_CHAR_APPEARING extends AbstractClientPacket {
|
||||
*/
|
||||
private final SpawnService spawnService;
|
||||
|
||||
/**
|
||||
* @param spawnService the spawn service
|
||||
*/
|
||||
@Inject
|
||||
public CM_CHAR_APPEARING(SpawnService spawnService) {
|
||||
this.spawnService = spawnService;
|
||||
|
||||
@@ -49,11 +49,22 @@ public class CM_CHAR_CHAT extends AbstractClientPacket {
|
||||
*/
|
||||
private final ChatService chatService;
|
||||
|
||||
/**
|
||||
* The message
|
||||
*/
|
||||
private String message;
|
||||
/**
|
||||
* The message destination
|
||||
*/
|
||||
private ChatMessageType destination;
|
||||
|
||||
/**
|
||||
* The message target
|
||||
*/
|
||||
private String target;
|
||||
|
||||
/**
|
||||
* @param chatService the chat service
|
||||
*/
|
||||
@Inject
|
||||
public CM_CHAR_CHAT(ChatService chatService) {
|
||||
this.chatService = chatService;
|
||||
|
||||
@@ -125,6 +125,9 @@ public class CM_CHAR_CREATE extends AbstractClientPacket {
|
||||
*/
|
||||
private CharacterFace face;
|
||||
|
||||
/**
|
||||
* @param characterService the character service
|
||||
*/
|
||||
@Inject
|
||||
public CM_CHAR_CREATE(CharacterService characterService) {
|
||||
this.characterService = characterService;
|
||||
|
||||
@@ -50,20 +50,50 @@ public class CM_CHAR_MOVE extends AbstractClientPacket {
|
||||
private final CharacterService charService;
|
||||
|
||||
// packet
|
||||
/**
|
||||
* The movement target
|
||||
*/
|
||||
private Coordinate target;
|
||||
/**
|
||||
* The movement origin
|
||||
*/
|
||||
private Coordinate origin;
|
||||
/**
|
||||
* The movement type
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private MovementType type;
|
||||
|
||||
/**
|
||||
* Defines the movement action type
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public enum MovementType {
|
||||
MOUSE(0x01), KEYBOARD(0x00);
|
||||
/**
|
||||
* The move action was issued by the mouse
|
||||
*/
|
||||
MOUSE(0x01),
|
||||
/**
|
||||
* The move action was issued by the keyboard
|
||||
*/
|
||||
KEYBOARD(0x00);
|
||||
|
||||
/**
|
||||
* The type id
|
||||
*/
|
||||
public final int id;
|
||||
|
||||
/**
|
||||
* @param id the type id
|
||||
*/
|
||||
MovementType(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id the type id
|
||||
* @return the {@link MovementType} represented by <code>id</code>
|
||||
*/
|
||||
public static MovementType fromID(int id) {
|
||||
for (final MovementType type : values()) {
|
||||
if (type.id == id)
|
||||
@@ -73,6 +103,9 @@ public class CM_CHAR_MOVE extends AbstractClientPacket {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param charService the character service
|
||||
*/
|
||||
@Inject
|
||||
public CM_CHAR_MOVE(CharacterService charService) {
|
||||
this.charService = charService;
|
||||
|
||||
@@ -40,10 +40,19 @@ public class CM_CHAR_POSITION extends AbstractClientPacket {
|
||||
*/
|
||||
private final CharacterService charService;
|
||||
|
||||
/**
|
||||
* The current position point
|
||||
*/
|
||||
private Point3D point;
|
||||
/**
|
||||
* Extra data -> vehicle id
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private int extra; // vehicle id
|
||||
|
||||
/**
|
||||
* @param charService the character service
|
||||
*/
|
||||
@Inject
|
||||
public CM_CHAR_POSITION(CharacterService charService) {
|
||||
this.charService = charService;
|
||||
|
||||
@@ -50,6 +50,9 @@ public class CM_CHAR_SELECT extends AbstractClientPacket {
|
||||
*/
|
||||
private int slot;
|
||||
|
||||
/**
|
||||
* @param characterDao the character dao
|
||||
*/
|
||||
@Inject
|
||||
public CM_CHAR_SELECT(CharacterDAO characterDao) {
|
||||
this.characterDao = characterDao;
|
||||
|
||||
@@ -40,6 +40,9 @@ public class CM_ENTER_WORLD extends AbstractClientPacket {
|
||||
*/
|
||||
public static final int OPCODE = 0x11;
|
||||
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private final Logger log = LoggerFactory.getLogger(CM_ENTER_WORLD.class);
|
||||
|
||||
/**
|
||||
@@ -47,6 +50,9 @@ public class CM_ENTER_WORLD extends AbstractClientPacket {
|
||||
*/
|
||||
private final CharacterService characterService;
|
||||
|
||||
/**
|
||||
* @param characterService the character service
|
||||
*/
|
||||
@Inject
|
||||
public CM_ENTER_WORLD(CharacterService characterService) {
|
||||
this.characterService = characterService;
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* This file is part of l2jserver2 <l2jserver2.com>.
|
||||
*
|
||||
* l2jserver2 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.
|
||||
*
|
||||
* l2jserver2 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 l2jserver2. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.game.net.packet.client;
|
||||
|
||||
import org.jboss.netty.buffer.ChannelBuffer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.l2jserver.game.net.Lineage2Client;
|
||||
import com.l2jserver.game.net.packet.AbstractClientPacket;
|
||||
|
||||
/**
|
||||
* The client is requesting a logout. Currently, when this packet is received
|
||||
* the connection is immediately closed.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class CM_EXT_REQ_SHORTCUT_REGISTRY extends AbstractClientPacket {
|
||||
/**
|
||||
* The packet OPCODE1
|
||||
*/
|
||||
public static final int OPCODE1 = 0xd0;
|
||||
/**
|
||||
* The packet OPCODE2
|
||||
*/
|
||||
public static final int OPCODE2 = 0x3d;
|
||||
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(CM_EXT_REQ_SHORTCUT_REGISTRY.class);
|
||||
|
||||
/**
|
||||
* The shortcut type
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private int type;
|
||||
/**
|
||||
* The shortcut ID
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private int id;
|
||||
@SuppressWarnings("unused")
|
||||
private int slot;
|
||||
@SuppressWarnings("unused")
|
||||
private int page;
|
||||
@SuppressWarnings("unused")
|
||||
private int lvl;
|
||||
@SuppressWarnings("unused")
|
||||
private int characterType;
|
||||
|
||||
@Override
|
||||
public void read(Lineage2Client conn, ChannelBuffer buffer) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(final Lineage2Client conn) {
|
||||
log.debug("Logging out client {}", conn);
|
||||
conn.close();
|
||||
}
|
||||
}
|
||||
@@ -52,6 +52,9 @@ public class CM_GG_KEY extends AbstractClientPacket {
|
||||
*/
|
||||
private byte[] key = new byte[8];
|
||||
|
||||
/**
|
||||
* @param ggService the gameguard service
|
||||
*/
|
||||
@Inject
|
||||
public CM_GG_KEY(GameGuardService ggService) {
|
||||
this.ggService = ggService;
|
||||
|
||||
@@ -48,6 +48,9 @@ public class CM_GOTO_LOBBY extends AbstractClientPacket {
|
||||
*/
|
||||
private final CharacterDAO characterDao;
|
||||
|
||||
/**
|
||||
* @param characterDao the character dao
|
||||
*/
|
||||
@Inject
|
||||
public CM_GOTO_LOBBY(CharacterDAO characterDao) {
|
||||
this.characterDao = characterDao;
|
||||
|
||||
@@ -43,6 +43,9 @@ public class CM_ITEM_DESTROY extends AbstractClientPacket {
|
||||
* The {@link ItemService}
|
||||
*/
|
||||
private final ItemService itemService;
|
||||
/**
|
||||
* The {@link ItemID} provider
|
||||
*/
|
||||
private final ItemIDProvider itemIdProvider;
|
||||
|
||||
/**
|
||||
|
||||
@@ -47,6 +47,9 @@ public class CM_ITEM_DROP extends AbstractClientPacket {
|
||||
* The {@link ItemService}
|
||||
*/
|
||||
private final ItemService itemService;
|
||||
/**
|
||||
* The {@link ItemID} provider
|
||||
*/
|
||||
private final ItemIDProvider itemIdProvider;
|
||||
|
||||
/**
|
||||
|
||||
@@ -64,6 +64,9 @@ public class CM_PROTOCOL_VERSION extends AbstractClientPacket {
|
||||
*/
|
||||
private ProtocolVersion version;
|
||||
|
||||
/**
|
||||
* @param keygen the keygen service
|
||||
*/
|
||||
@Inject
|
||||
public CM_PROTOCOL_VERSION(BlowfishKeygenService keygen) {
|
||||
this.keygen = keygen;
|
||||
@@ -115,8 +118,4 @@ public class CM_PROTOCOL_VERSION extends AbstractClientPacket {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public ProtocolVersion getVersion() {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +64,9 @@ public class CM_REQUEST_CHAR_TEMPLATE extends AbstractClientPacket {
|
||||
*/
|
||||
private final CharacterTemplateIDProvider idFactory;
|
||||
|
||||
/**
|
||||
* @param idFactory the character template id provider
|
||||
*/
|
||||
@Inject
|
||||
public CM_REQUEST_CHAR_TEMPLATE(CharacterTemplateIDProvider idFactory) {
|
||||
this.idFactory = idFactory;
|
||||
|
||||
@@ -48,6 +48,10 @@ public class CM_RESTART extends AbstractClientPacket {
|
||||
*/
|
||||
private final CharacterDAO charDao;
|
||||
|
||||
/**
|
||||
* @param charService the character service
|
||||
* @param charDao the character dao
|
||||
*/
|
||||
@Inject
|
||||
public CM_RESTART(CharacterService charService, CharacterDAO charDao) {
|
||||
this.charService = charService;
|
||||
|
||||
@@ -48,12 +48,22 @@ public class SM_ACTOR_ATTACK extends AbstractServerPacket {
|
||||
*/
|
||||
private final List<AttackHit> hits = CollectionFactory.newList();
|
||||
|
||||
/**
|
||||
* @param attacker
|
||||
* the attacked
|
||||
* @param hits
|
||||
* the hits
|
||||
*/
|
||||
public SM_ACTOR_ATTACK(Actor attacker, AttackHit... hits) {
|
||||
super(OPCODE);
|
||||
this.attacker = attacker;
|
||||
Collections.addAll(this.hits, hits);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param hits
|
||||
* the hits
|
||||
*/
|
||||
public SM_ACTOR_ATTACK(AttackHit... hits) {
|
||||
this(hits[0].getAttacker(), hits);
|
||||
}
|
||||
@@ -90,6 +100,13 @@ public class SM_ACTOR_ATTACK extends AbstractServerPacket {
|
||||
buffer.writeInt(first.getTarget().getPoint().getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new hit
|
||||
*
|
||||
* @param hit
|
||||
* the hit
|
||||
* @return this instance
|
||||
*/
|
||||
public SM_ACTOR_ATTACK add(AttackHit hit) {
|
||||
hits.add(hit);
|
||||
return this;
|
||||
|
||||
@@ -54,6 +54,11 @@ public class SM_ACTOR_CHAT extends AbstractServerPacket {
|
||||
*/
|
||||
private int messageID = 0;
|
||||
|
||||
/**
|
||||
* @param character the actor
|
||||
* @param destination the destination
|
||||
* @param message the message
|
||||
*/
|
||||
public SM_ACTOR_CHAT(Actor character, ChatMessageType destination, String message) {
|
||||
super(OPCODE);
|
||||
this.actor = character;
|
||||
@@ -61,6 +66,11 @@ public class SM_ACTOR_CHAT extends AbstractServerPacket {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param actor the actor
|
||||
* @param destination the destination
|
||||
* @param messageID the message id
|
||||
*/
|
||||
public SM_ACTOR_CHAT(Actor actor, ChatMessageType destination, int messageID) {
|
||||
super(OPCODE);
|
||||
this.actor = actor;
|
||||
|
||||
@@ -40,6 +40,10 @@ public class SM_ACTOR_DIE extends AbstractServerPacket {
|
||||
*/
|
||||
private final Actor actor;
|
||||
|
||||
/**
|
||||
* @param actor
|
||||
* the actor
|
||||
*/
|
||||
public SM_ACTOR_DIE(Actor actor) {
|
||||
super(OPCODE);
|
||||
this.actor = actor;
|
||||
|
||||
@@ -45,6 +45,10 @@ public class SM_ACTOR_MOVE extends AbstractServerPacket {
|
||||
*/
|
||||
private Coordinate target;
|
||||
|
||||
/**
|
||||
* @param actor the actor
|
||||
* @param target the target
|
||||
*/
|
||||
public SM_ACTOR_MOVE(Actor actor, Coordinate target) {
|
||||
super(OPCODE);
|
||||
this.actor = actor;
|
||||
|
||||
@@ -39,6 +39,9 @@ public class SM_ACTOR_POSITION extends AbstractServerPacket {
|
||||
*/
|
||||
private final Actor actor;
|
||||
|
||||
/**
|
||||
* @param actor the actor
|
||||
*/
|
||||
public SM_ACTOR_POSITION(Actor actor) {
|
||||
super(OPCODE);
|
||||
this.actor = actor;
|
||||
|
||||
@@ -44,29 +44,151 @@ public class SM_ACTOR_STATUS_UPDATE extends AbstractServerPacket {
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public enum Stat {
|
||||
LEVEL(0x01), EXPERIENCE(0x02), STR(0x03), DEX(0x04), CON(0x05), INT(
|
||||
0x06), WIT(0x07), MEN(0x08),
|
||||
/**
|
||||
* Updates the character level
|
||||
*/
|
||||
LEVEL(0x01),
|
||||
/**
|
||||
* Updates the character experience
|
||||
*/
|
||||
EXPERIENCE(0x02),
|
||||
/**
|
||||
* Updates the character strength
|
||||
*/
|
||||
STR(0x03),
|
||||
/**
|
||||
* Updates the character dexterity
|
||||
*/
|
||||
DEX(0x04),
|
||||
|
||||
HP(0x09), MAX_HP(0x0a), MP(0x0b), MAX_MP(0x0c),
|
||||
/**
|
||||
* Updates the character concentration
|
||||
*/
|
||||
CON(0x05),
|
||||
/**
|
||||
* Updates the character intelligence
|
||||
*/
|
||||
INT(0x06),
|
||||
/**
|
||||
* Updates the character witness
|
||||
*/
|
||||
WIT(0x07),
|
||||
/**
|
||||
* Updates the character mentality
|
||||
*/
|
||||
MEN(0x08),
|
||||
/**
|
||||
* Updates the character hp
|
||||
*/
|
||||
HP(0x09),
|
||||
/**
|
||||
* Updates the character maximum hp
|
||||
*/
|
||||
MAX_HP(0x0a),
|
||||
/**
|
||||
* Updates the character hp
|
||||
*/
|
||||
MP(0x0b),
|
||||
/**
|
||||
* Updates the character maximum mp
|
||||
*/
|
||||
MAX_MP(0x0c),
|
||||
/**
|
||||
* Updates the character sp
|
||||
*/
|
||||
SP(0x0d),
|
||||
/**
|
||||
* Updates the character load
|
||||
*/
|
||||
LOAD(0x0e),
|
||||
/**
|
||||
* Updates the character maximum load
|
||||
*/
|
||||
MAX_LOAD(0x0f),
|
||||
/**
|
||||
* Updates the character physical attack
|
||||
*/
|
||||
PHYSICAL_ATK(0x11),
|
||||
/**
|
||||
* Updates the character attack speed
|
||||
*/
|
||||
ATTACK_SPEED(0x12),
|
||||
/**
|
||||
* Updates the character physical defense
|
||||
*/
|
||||
PHYSICAL_DEFENSE(0x13),
|
||||
/**
|
||||
* Updates the character evasion
|
||||
*/
|
||||
EVASION(0x14),
|
||||
/**
|
||||
* Updates the character accuracy
|
||||
*/
|
||||
ACCURACY(0x15),
|
||||
/**
|
||||
* Updates the character critical
|
||||
*/
|
||||
CRITICAL(0x16),
|
||||
/**
|
||||
* Updates the character magical attack
|
||||
*/
|
||||
MAGICAL_ATTACK(0x17),
|
||||
/**
|
||||
* Updates the character cast speed
|
||||
*/
|
||||
CAST_SPEED(0x18),
|
||||
/**
|
||||
* Updates the character magical defense
|
||||
*/
|
||||
MAGICAL_DEFENSE(0x19),
|
||||
|
||||
SP(0x0d), LOAD(0x0e), MAX_LOAD(0x0f),
|
||||
/**
|
||||
* Updates the character pvp flag
|
||||
*/
|
||||
PVP_FLAG(0x1a),
|
||||
|
||||
PHYSICAL_ATK(0x11), ATTACK_SPEED(0x12), PHYSICAL_DEFENSE(0x13), EVASION(
|
||||
0x14), ACCURACY(0x15), CRITICAL(0x16), MAGICAL_ATTACK(0x17), CAST_SPEED(
|
||||
0x18), MAGICAL_DEFENSE(0x19), PVP_FLAG(0x1a), KARMA(0x1b),
|
||||
/**
|
||||
* Updates the character karma
|
||||
*/
|
||||
KARMA(0x1b),
|
||||
|
||||
CP(0x21), MAX_CP(0x22);
|
||||
/**
|
||||
* Updates the character cp
|
||||
*/
|
||||
CP(0x21),
|
||||
|
||||
/**
|
||||
* Updates the character max cp
|
||||
*/
|
||||
MAX_CP(0x22);
|
||||
|
||||
/**
|
||||
* The stat id
|
||||
*/
|
||||
public final int id;
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* the stat id
|
||||
*/
|
||||
Stat(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The set of updates to be sent
|
||||
*/
|
||||
private final Map<Stat, Integer> update = CollectionFactory.newMap();
|
||||
/**
|
||||
* The actor to be updated
|
||||
*/
|
||||
private final Actor actor;
|
||||
|
||||
/**
|
||||
* @param actor
|
||||
* the actor
|
||||
*/
|
||||
public SM_ACTOR_STATUS_UPDATE(Actor actor) {
|
||||
super(OPCODE);
|
||||
this.actor = actor;
|
||||
@@ -83,6 +205,13 @@ public class SM_ACTOR_STATUS_UPDATE extends AbstractServerPacket {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param stat
|
||||
* the stat
|
||||
* @param value
|
||||
* the stat value
|
||||
* @return this instances
|
||||
*/
|
||||
public SM_ACTOR_STATUS_UPDATE add(Stat stat, int value) {
|
||||
update.put(stat, value);
|
||||
return this;
|
||||
|
||||
@@ -83,11 +83,17 @@ public class SM_CHAR_CREATE_FAIL extends AbstractServerPacket {
|
||||
*/
|
||||
public final int id;
|
||||
|
||||
/**
|
||||
* @param id the reason id
|
||||
*/
|
||||
Reason(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param reason the reason
|
||||
*/
|
||||
public SM_CHAR_CREATE_FAIL(Reason reason) {
|
||||
super(OPCODE);
|
||||
this.reason = reason;
|
||||
|
||||
@@ -37,6 +37,9 @@ public class SM_CHAR_CREATE_OK extends AbstractServerPacket {
|
||||
*/
|
||||
public static final SM_CHAR_CREATE_OK INSTANCE = new SM_CHAR_CREATE_OK();
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*/
|
||||
public SM_CHAR_CREATE_OK() {
|
||||
super(OPCODE);
|
||||
}
|
||||
|
||||
@@ -76,6 +76,9 @@ public class SM_CHAR_INFO extends AbstractServerPacket {
|
||||
*/
|
||||
private L2Character character;
|
||||
|
||||
/**
|
||||
* @param character the character
|
||||
*/
|
||||
public SM_CHAR_INFO(L2Character character) {
|
||||
super(OPCODE);
|
||||
this.character = character;
|
||||
@@ -338,6 +341,16 @@ public class SM_CHAR_INFO extends AbstractServerPacket {
|
||||
buffer.writeInt(0x00); // special effects
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the paperdoll object id
|
||||
*
|
||||
* @param buffer
|
||||
* the buffer
|
||||
* @param character
|
||||
* the character
|
||||
* @param paperdoll
|
||||
* the slot
|
||||
*/
|
||||
private void writePaperdollObjectID(ChannelBuffer buffer,
|
||||
L2Character character, InventoryPaperdoll paperdoll) {
|
||||
final Item item = character.getInventory().getItem(paperdoll);
|
||||
@@ -347,6 +360,16 @@ public class SM_CHAR_INFO extends AbstractServerPacket {
|
||||
buffer.writeInt(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the paperdoll item id
|
||||
*
|
||||
* @param buffer
|
||||
* the buffer
|
||||
* @param character
|
||||
* the character
|
||||
* @param paperdoll
|
||||
* the slot
|
||||
*/
|
||||
private void writePaperdollItemID(ChannelBuffer buffer,
|
||||
L2Character character, InventoryPaperdoll paperdoll) {
|
||||
final Item item = character.getInventory().getItem(paperdoll);
|
||||
@@ -356,6 +379,16 @@ public class SM_CHAR_INFO extends AbstractServerPacket {
|
||||
buffer.writeInt(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the paperdoll augument id
|
||||
*
|
||||
* @param buffer
|
||||
* the buffer
|
||||
* @param character
|
||||
* the character
|
||||
* @param paperdoll
|
||||
* the slot
|
||||
*/
|
||||
private void writePaperdollAugumentID(ChannelBuffer buffer,
|
||||
L2Character character, InventoryPaperdoll paperdoll) {
|
||||
buffer.writeInt(0x00);
|
||||
|
||||
@@ -59,8 +59,15 @@ public class SM_CHAR_INFO_BROADCAST extends AbstractServerPacket {
|
||||
*/
|
||||
public static final int OPCODE = 0x31;
|
||||
|
||||
/**
|
||||
* The character
|
||||
*/
|
||||
private final L2Character character;
|
||||
|
||||
/**
|
||||
* @param character
|
||||
* the character
|
||||
*/
|
||||
public SM_CHAR_INFO_BROADCAST(L2Character character) {
|
||||
super(OPCODE);
|
||||
this.character = character;
|
||||
@@ -248,6 +255,16 @@ public class SM_CHAR_INFO_BROADCAST extends AbstractServerPacket {
|
||||
buffer.writeInt(0x00); // special effect
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the paperdoll item id
|
||||
*
|
||||
* @param buffer
|
||||
* the buffer
|
||||
* @param character
|
||||
* the character
|
||||
* @param paperdoll
|
||||
* the slot
|
||||
*/
|
||||
private void writePaperdollItemID(ChannelBuffer buffer,
|
||||
L2Character character, InventoryPaperdoll paperdoll) {
|
||||
final Item item = character.getInventory().getItem(paperdoll);
|
||||
@@ -257,6 +274,16 @@ public class SM_CHAR_INFO_BROADCAST extends AbstractServerPacket {
|
||||
buffer.writeInt(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the paperdoll augument id
|
||||
*
|
||||
* @param buffer
|
||||
* the buffer
|
||||
* @param character
|
||||
* the character
|
||||
* @param paperdoll
|
||||
* the slot
|
||||
*/
|
||||
private void writePaperdollAugumentID(ChannelBuffer buffer,
|
||||
L2Character character, InventoryPaperdoll paperdoll) {
|
||||
buffer.writeInt(0x00);
|
||||
|
||||
@@ -38,6 +38,9 @@ public class SM_CHAR_INFO_EXTRA extends AbstractServerPacket {
|
||||
*/
|
||||
private L2Character character;
|
||||
|
||||
/**
|
||||
* @param character the character
|
||||
*/
|
||||
public SM_CHAR_INFO_EXTRA(L2Character character) {
|
||||
super(OPCODE);
|
||||
this.character = character;
|
||||
|
||||
@@ -44,6 +44,9 @@ public class SM_CHAR_INVENTORY extends AbstractServerPacket {
|
||||
*/
|
||||
private boolean showWindow = false;
|
||||
|
||||
/**
|
||||
* @param inventory the inventory
|
||||
*/
|
||||
public SM_CHAR_INVENTORY(CharacterInventory inventory) {
|
||||
super(OPCODE);
|
||||
this.inventory = inventory;
|
||||
|
||||
@@ -79,6 +79,16 @@ public class SM_CHAR_LIST extends AbstractServerPacket {
|
||||
*/
|
||||
private final L2Character[] characters;
|
||||
|
||||
/**
|
||||
* @param loginName
|
||||
* the account id
|
||||
* @param sessionId
|
||||
* the session id
|
||||
* @param lastCharacterId
|
||||
* the last character used
|
||||
* @param characters
|
||||
* the characters
|
||||
*/
|
||||
public SM_CHAR_LIST(String loginName, int sessionId, int lastCharacterId,
|
||||
L2Character... characters) {
|
||||
super(OPCODE);
|
||||
@@ -88,12 +98,26 @@ public class SM_CHAR_LIST extends AbstractServerPacket {
|
||||
this.characters = characters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param session
|
||||
* the session
|
||||
* @param characters
|
||||
* the characters
|
||||
* @return an {@link SM_CHAR_LIST} instance
|
||||
*/
|
||||
public static SM_CHAR_LIST fromL2Session(Lineage2Session session,
|
||||
L2Character... characters) {
|
||||
return new SM_CHAR_LIST(session.getAccountID().getID(),
|
||||
session.getPlayKey2(), -1, characters);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param session
|
||||
* the session
|
||||
* @param characters
|
||||
* the characters
|
||||
* @return an {@link SM_CHAR_LIST} instance
|
||||
*/
|
||||
public static SM_CHAR_LIST fromL2Session(Lineage2Session session,
|
||||
Collection<L2Character> characters) {
|
||||
return fromL2Session(session,
|
||||
@@ -220,6 +244,16 @@ public class SM_CHAR_LIST extends AbstractServerPacket {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the paperdoll item id
|
||||
*
|
||||
* @param buffer
|
||||
* the buffer
|
||||
* @param character
|
||||
* the character
|
||||
* @param paperdoll
|
||||
* the slot
|
||||
*/
|
||||
private void writePaperdollItemID(ChannelBuffer buffer,
|
||||
L2Character character, InventoryPaperdoll paperdoll) {
|
||||
final Item item = character.getInventory().getItem(paperdoll);
|
||||
|
||||
@@ -38,6 +38,9 @@ public class SM_CHAR_MOVE_TYPE extends AbstractServerPacket {
|
||||
*/
|
||||
private final L2Character character;
|
||||
|
||||
/**
|
||||
* @param character the character
|
||||
*/
|
||||
public SM_CHAR_MOVE_TYPE(L2Character character) {
|
||||
super(OPCODE);
|
||||
this.character = character;
|
||||
|
||||
@@ -37,6 +37,9 @@ public class SM_CHAR_OPEN_MAP extends AbstractServerPacket {
|
||||
*/
|
||||
private final int mapID;
|
||||
|
||||
/**
|
||||
* @param mapID the map id
|
||||
*/
|
||||
public SM_CHAR_OPEN_MAP(int mapID) {
|
||||
super(OPCODE);
|
||||
this.mapID = mapID;
|
||||
|
||||
@@ -37,15 +37,25 @@ public class SM_CHAR_RESTART extends AbstractServerPacket {
|
||||
*/
|
||||
private boolean state;
|
||||
|
||||
/**
|
||||
* @param state
|
||||
* the state
|
||||
*/
|
||||
public SM_CHAR_RESTART(boolean state) {
|
||||
super(OPCODE);
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an OK instance of this packet
|
||||
*/
|
||||
public static SM_CHAR_RESTART ok() {
|
||||
return new SM_CHAR_RESTART(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an FAILED instance of this packet
|
||||
*/
|
||||
public static SM_CHAR_RESTART denied() {
|
||||
return new SM_CHAR_RESTART(false);
|
||||
}
|
||||
|
||||
@@ -41,6 +41,9 @@ public class SM_CHAR_SELECTED extends AbstractServerPacket {
|
||||
*/
|
||||
private final L2Character character;
|
||||
|
||||
/**
|
||||
* @param character the character
|
||||
*/
|
||||
public SM_CHAR_SELECTED(L2Character character) {
|
||||
super(OPCODE);
|
||||
this.character = character;
|
||||
|
||||
@@ -39,6 +39,10 @@ public class SM_CHAR_SHORTCUT_LIST extends AbstractServerPacket {
|
||||
*/
|
||||
private final CharacterShortcutContainer shortcuts;
|
||||
|
||||
/**
|
||||
* @param shortcuts
|
||||
* the shortcuts container
|
||||
*/
|
||||
public SM_CHAR_SHORTCUT_LIST(CharacterShortcutContainer shortcuts) {
|
||||
super(OPCODE);
|
||||
this.shortcuts = shortcuts;
|
||||
|
||||
@@ -38,6 +38,10 @@ public class SM_CHAR_SHORTCUT_REGISTER extends AbstractServerPacket {
|
||||
*/
|
||||
private final CharacterShortcut shortcut;
|
||||
|
||||
/**
|
||||
* @param shortcut
|
||||
* the shortcut registered
|
||||
*/
|
||||
public SM_CHAR_SHORTCUT_REGISTER(CharacterShortcut shortcut) {
|
||||
super(OPCODE);
|
||||
this.shortcut = shortcut;
|
||||
|
||||
@@ -33,8 +33,14 @@ public class SM_CHAR_STOP extends AbstractServerPacket {
|
||||
*/
|
||||
public static final int OPCODE = 0x47;
|
||||
|
||||
/**
|
||||
* The character
|
||||
*/
|
||||
private L2Character character;
|
||||
|
||||
/**
|
||||
* @param character the character
|
||||
*/
|
||||
public SM_CHAR_STOP(L2Character character) {
|
||||
super(OPCODE);
|
||||
this.character = character;
|
||||
|
||||
@@ -38,14 +38,27 @@ public class SM_CHAR_TARGET extends AbstractServerPacket {
|
||||
* The selected character
|
||||
*/
|
||||
private final Actor object;
|
||||
/**
|
||||
* The name color
|
||||
*/
|
||||
private int color;
|
||||
|
||||
/**
|
||||
* @param object
|
||||
* the target
|
||||
* @param color
|
||||
* the name color
|
||||
*/
|
||||
public SM_CHAR_TARGET(Actor object, int color) {
|
||||
super(OPCODE);
|
||||
this.object = object;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object
|
||||
* the target
|
||||
*/
|
||||
public SM_CHAR_TARGET(Actor object) {
|
||||
this(object, 0);
|
||||
}
|
||||
|
||||
@@ -39,6 +39,9 @@ public class SM_CHAR_TARGET_UNSELECT extends AbstractServerPacket {
|
||||
*/
|
||||
private final L2Character character;
|
||||
|
||||
/**
|
||||
* @param character the character
|
||||
*/
|
||||
public SM_CHAR_TARGET_UNSELECT(L2Character character) {
|
||||
super(OPCODE);
|
||||
this.character = character;
|
||||
|
||||
@@ -44,6 +44,10 @@ public class SM_CHAR_TELEPORT extends AbstractServerPacket {
|
||||
*/
|
||||
private final Point3D point;
|
||||
|
||||
/**
|
||||
* @param character the character
|
||||
* @param point the teleport point
|
||||
*/
|
||||
public SM_CHAR_TELEPORT(L2Character character, Point3D point) {
|
||||
super(OPCODE);
|
||||
this.character = character;
|
||||
|
||||
@@ -38,6 +38,9 @@ public class SM_CHAR_TEMPLATE extends AbstractServerPacket {
|
||||
*/
|
||||
private CharacterTemplate[] templates;
|
||||
|
||||
/**
|
||||
* @param templates the character templates
|
||||
*/
|
||||
public SM_CHAR_TEMPLATE(CharacterTemplate... templates) {
|
||||
super(OPCODE);
|
||||
this.templates = templates;
|
||||
|
||||
@@ -41,16 +41,25 @@ public class SM_COMMUNITY_HTML extends AbstractServerPacket {
|
||||
*/
|
||||
private final String html;
|
||||
|
||||
/**
|
||||
* @param html the html
|
||||
*/
|
||||
public SM_COMMUNITY_HTML(String html) {
|
||||
super(OPCODE);
|
||||
this.html = html;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param html the html
|
||||
*/
|
||||
public SM_COMMUNITY_HTML(Html html) {
|
||||
super(OPCODE);
|
||||
this.html = html.toHtml();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param template the html template
|
||||
*/
|
||||
public SM_COMMUNITY_HTML(HtmlTemplate template) {
|
||||
super(OPCODE);
|
||||
this.html = template.toHtmlString();
|
||||
|
||||
@@ -33,6 +33,9 @@ public class SM_FORT_INFO extends AbstractServerPacket {
|
||||
*/
|
||||
public static final int OPCODE = 0xfe;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*/
|
||||
public SM_FORT_INFO() {
|
||||
super(OPCODE);
|
||||
}
|
||||
|
||||
@@ -33,9 +33,15 @@ public class SM_GG_QUERY extends AbstractServerPacket {
|
||||
* The packet OPCODE
|
||||
*/
|
||||
public static final int OPCODE = 0x74;
|
||||
|
||||
/**
|
||||
* The GG key
|
||||
*/
|
||||
private final int[] key;
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* the game guard key
|
||||
*/
|
||||
public SM_GG_QUERY(int[] key) {
|
||||
super(OPCODE);
|
||||
Preconditions.checkArgument(key.length == 4,
|
||||
@@ -43,6 +49,16 @@ public class SM_GG_QUERY extends AbstractServerPacket {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key1
|
||||
* the game guard key 1
|
||||
* @param key2
|
||||
* the game guard key 2
|
||||
* @param key3
|
||||
* the game guard key 3
|
||||
* @param key4
|
||||
* the game guard key 4
|
||||
*/
|
||||
public SM_GG_QUERY(int key1, int key2, int key3, int key4) {
|
||||
super(OPCODE);
|
||||
this.key = new int[4];
|
||||
|
||||
@@ -45,32 +45,62 @@ public class SM_HTML extends AbstractServerPacket {
|
||||
*/
|
||||
private final String html;
|
||||
|
||||
/**
|
||||
* @param npc
|
||||
* the npc instance
|
||||
* @param html
|
||||
* the html
|
||||
*/
|
||||
public SM_HTML(NPC npc, String html) {
|
||||
super(OPCODE);
|
||||
this.npc = npc;
|
||||
this.html = html;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param npc
|
||||
* the npc instance
|
||||
* @param html
|
||||
* the html
|
||||
*/
|
||||
public SM_HTML(NPC npc, Html html) {
|
||||
super(OPCODE);
|
||||
this.npc = npc;
|
||||
this.html = html.toHtml();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param npc
|
||||
* the npc instance
|
||||
* @param template
|
||||
* the html template
|
||||
*/
|
||||
public SM_HTML(NPC npc, HtmlTemplate template) {
|
||||
super(OPCODE);
|
||||
this.npc = npc;
|
||||
this.html = template.toHtmlString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param html
|
||||
* the html
|
||||
*/
|
||||
public SM_HTML(String html) {
|
||||
this(null, html);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param html
|
||||
* the html
|
||||
*/
|
||||
public SM_HTML(Html html) {
|
||||
this(null, html);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param template
|
||||
* the html template
|
||||
*/
|
||||
public SM_HTML(HtmlTemplate template) {
|
||||
this(null, template);
|
||||
}
|
||||
|
||||
@@ -32,9 +32,14 @@ public class SM_ITEM_GROUND extends AbstractServerPacket {
|
||||
* The packet OPCODE
|
||||
*/
|
||||
public static final int OPCODE = 0x16;
|
||||
|
||||
/**
|
||||
* The item that is on the ground
|
||||
*/
|
||||
private final Item item;
|
||||
|
||||
/**
|
||||
* @param item the item that is on the ground
|
||||
*/
|
||||
public SM_ITEM_GROUND(Item item) {
|
||||
super(OPCODE);
|
||||
this.item = item;
|
||||
|
||||
@@ -49,6 +49,12 @@ public class SM_KEY extends AbstractServerPacket {
|
||||
*/
|
||||
private boolean status;
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* the cryptography key
|
||||
* @param status
|
||||
* the status
|
||||
*/
|
||||
public SM_KEY(Lineage2CryptographyKey key, boolean status) {
|
||||
super(OPCODE);
|
||||
this.key = Arrays.copyOfRange(key.key, 0, 8);
|
||||
|
||||
@@ -38,6 +38,9 @@ public class SM_MANOR_LIST extends AbstractServerPacket {
|
||||
*/
|
||||
private String[] manors;
|
||||
|
||||
/**
|
||||
* @param manors the manors
|
||||
*/
|
||||
public SM_MANOR_LIST(String... manors) {
|
||||
super(OPCODE);
|
||||
this.manors = manors;
|
||||
|
||||
@@ -34,9 +34,14 @@ public class SM_NPC_INFO extends AbstractServerPacket {
|
||||
* The packet OPCODE
|
||||
*/
|
||||
public static final int OPCODE = 0x0c;
|
||||
|
||||
/**
|
||||
* The {@link NPC}
|
||||
*/
|
||||
private final NPC npc;
|
||||
|
||||
/**
|
||||
* @param npc the npc
|
||||
*/
|
||||
public SM_NPC_INFO(NPC npc) {
|
||||
super(OPCODE);
|
||||
this.npc = npc;
|
||||
|
||||
@@ -39,6 +39,10 @@ public class SM_OBJECT_REMOVE extends AbstractServerPacket {
|
||||
*/
|
||||
private final PositionableObject object;
|
||||
|
||||
/**
|
||||
* @param object
|
||||
* the object to be removed
|
||||
*/
|
||||
public SM_OBJECT_REMOVE(PositionableObject object) {
|
||||
super(OPCODE);
|
||||
this.object = object;
|
||||
|
||||
@@ -35,9 +35,15 @@ public class SM_SERVER_OBJECT extends AbstractServerPacket {
|
||||
* The packet OPCODE
|
||||
*/
|
||||
public static final int OPCODE = 0x92;
|
||||
|
||||
/**
|
||||
* The {@link NPC}
|
||||
*/
|
||||
private final NPC npc;
|
||||
|
||||
/**
|
||||
* @param npc
|
||||
* the npc
|
||||
*/
|
||||
public SM_SERVER_OBJECT(NPC npc) {
|
||||
super(OPCODE);
|
||||
this.npc = npc;
|
||||
|
||||
@@ -23,12 +23,14 @@ import org.jboss.netty.buffer.ChannelBuffer;
|
||||
import com.l2jserver.game.net.Lineage2Client;
|
||||
import com.l2jserver.game.net.SystemMessage;
|
||||
import com.l2jserver.game.net.packet.AbstractServerPacket;
|
||||
import com.l2jserver.model.game.Castle;
|
||||
import com.l2jserver.model.game.Fort;
|
||||
import com.l2jserver.model.game.Skill;
|
||||
import com.l2jserver.model.template.SkillTemplate;
|
||||
import com.l2jserver.model.template.item.ItemTemplate;
|
||||
import com.l2jserver.model.world.Actor;
|
||||
import com.l2jserver.model.world.Item;
|
||||
import com.l2jserver.model.world.NPC;
|
||||
import com.l2jserver.util.BufferUtils;
|
||||
import com.l2jserver.util.factory.CollectionFactory;
|
||||
|
||||
@@ -54,22 +56,69 @@ public class SM_SYSTEM_MESSAGE extends AbstractServerPacket {
|
||||
private List<SystemMessagePacketParameter> params = CollectionFactory
|
||||
.newList();
|
||||
|
||||
/**
|
||||
* System message parameter IDs
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface SystemMessagePacketParameter {
|
||||
/**
|
||||
* String parameter
|
||||
*/
|
||||
public static final byte TYPE_SYSTEM_STRING = 13;
|
||||
/**
|
||||
* Player name parameter
|
||||
*/
|
||||
public static final byte TYPE_PLAYER_NAME = 12;
|
||||
// id 11 - unknown
|
||||
/**
|
||||
* Instance name parameter
|
||||
*/
|
||||
public static final byte TYPE_INSTANCE_NAME = 10;
|
||||
/**
|
||||
* Element name parameter
|
||||
*/
|
||||
public static final byte TYPE_ELEMENT_NAME = 9;
|
||||
// id 8 - same as 3
|
||||
/**
|
||||
* Zone name parameter
|
||||
*/
|
||||
public static final byte TYPE_ZONE_NAME = 7;
|
||||
/**
|
||||
* {@link Item} number parameter
|
||||
*/
|
||||
public static final byte TYPE_ITEM_NUMBER = 6;
|
||||
/**
|
||||
* {@link Castle} name parameter
|
||||
*/
|
||||
public static final byte TYPE_CASTLE_NAME = 5;
|
||||
/**
|
||||
* {@link Skill} name parameter
|
||||
*/
|
||||
public static final byte TYPE_SKILL_NAME = 4;
|
||||
/**
|
||||
* {@link Item} name parameter
|
||||
*/
|
||||
public static final byte TYPE_ITEM_NAME = 3;
|
||||
/**
|
||||
* {@link NPC} name parameter
|
||||
*/
|
||||
public static final byte TYPE_NPC_NAME = 2;
|
||||
/**
|
||||
* Number parameter
|
||||
*/
|
||||
public static final byte TYPE_NUMBER = 1;
|
||||
/**
|
||||
* Text parameter
|
||||
*/
|
||||
public static final byte TYPE_TEXT = 0;
|
||||
|
||||
/**
|
||||
* @param conn
|
||||
* the connection
|
||||
* @param buffer
|
||||
* the buffer
|
||||
*/
|
||||
void write(Lineage2Client conn, ChannelBuffer buffer);
|
||||
}
|
||||
|
||||
@@ -93,6 +142,13 @@ public class SM_SYSTEM_MESSAGE extends AbstractServerPacket {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an string parameter
|
||||
*
|
||||
* @param text
|
||||
* the text
|
||||
* @return this instance
|
||||
*/
|
||||
public final SM_SYSTEM_MESSAGE addString(final String text) {
|
||||
params.add(new SystemMessagePacketParameter() {
|
||||
@Override
|
||||
@@ -126,6 +182,13 @@ public class SM_SYSTEM_MESSAGE extends AbstractServerPacket {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an number parameter
|
||||
*
|
||||
* @param number
|
||||
* the number
|
||||
* @return this instance
|
||||
*/
|
||||
public final SM_SYSTEM_MESSAGE addNumber(final int number) {
|
||||
params.add(new SystemMessagePacketParameter() {
|
||||
@Override
|
||||
@@ -137,6 +200,13 @@ public class SM_SYSTEM_MESSAGE extends AbstractServerPacket {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an item count parameter
|
||||
*
|
||||
* @param number
|
||||
* the number
|
||||
* @return this instance
|
||||
*/
|
||||
public final SM_SYSTEM_MESSAGE addItemCount(final long number) {
|
||||
params.add(new SystemMessagePacketParameter() {
|
||||
@Override
|
||||
@@ -148,6 +218,13 @@ public class SM_SYSTEM_MESSAGE extends AbstractServerPacket {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an the actor name
|
||||
*
|
||||
* @param actor
|
||||
* the actor
|
||||
* @return this instance
|
||||
*/
|
||||
public final SM_SYSTEM_MESSAGE addActorName(final Actor actor) {
|
||||
// params.add(new SystemMessagePacketParameter() {
|
||||
// @Override
|
||||
@@ -160,6 +237,13 @@ public class SM_SYSTEM_MESSAGE extends AbstractServerPacket {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the item name
|
||||
*
|
||||
* @param item
|
||||
* the item
|
||||
* @return this instance
|
||||
*/
|
||||
public final SM_SYSTEM_MESSAGE addItem(final ItemTemplate item) {
|
||||
params.add(new SystemMessagePacketParameter() {
|
||||
@Override
|
||||
@@ -171,10 +255,29 @@ public class SM_SYSTEM_MESSAGE extends AbstractServerPacket {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the item name
|
||||
*
|
||||
* @param item
|
||||
* the item
|
||||
* @return this instance
|
||||
*/
|
||||
public final SM_SYSTEM_MESSAGE addItem(final Item item) {
|
||||
return addItem(item.getTemplateID().getTemplate());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the zone name
|
||||
*
|
||||
* @param x
|
||||
* the x
|
||||
* @param y
|
||||
* the y
|
||||
* @param z
|
||||
* the z
|
||||
*
|
||||
* @return this instance
|
||||
*/
|
||||
public final SM_SYSTEM_MESSAGE addZoneName(final int x, final int y,
|
||||
final int z) {
|
||||
params.add(new SystemMessagePacketParameter() {
|
||||
@@ -189,6 +292,13 @@ public class SM_SYSTEM_MESSAGE extends AbstractServerPacket {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param skill
|
||||
* the skill template
|
||||
* @param level
|
||||
* the skill level
|
||||
* @return this instance
|
||||
*/
|
||||
public final SM_SYSTEM_MESSAGE addSkill(final SkillTemplate skill,
|
||||
final int level) {
|
||||
params.add(new SystemMessagePacketParameter() {
|
||||
@@ -202,6 +312,11 @@ public class SM_SYSTEM_MESSAGE extends AbstractServerPacket {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param skill
|
||||
* the skill
|
||||
* @return this instance
|
||||
*/
|
||||
public final SM_SYSTEM_MESSAGE addSkill(final Skill skill) {
|
||||
return addSkill(skill.getTemplate(), skill.getLevel());
|
||||
}
|
||||
|
||||
@@ -32,6 +32,9 @@ import com.l2jserver.model.id.provider.IDProvider;
|
||||
*/
|
||||
public class CharacterShortcutID extends
|
||||
AbstractModelID<Integer, CharacterShortcut> {
|
||||
/**
|
||||
* The {@link CharacterShortcutDAO} instance
|
||||
*/
|
||||
private final CharacterShortcutDAO shortcutDao;
|
||||
|
||||
/**
|
||||
|
||||
@@ -44,13 +44,25 @@ import com.l2jserver.util.jaxb.SkillTemplateIDAdapter;
|
||||
@XmlType(namespace = "http://schemas.l2jserver2.com/skill", name = "SkillType")
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class SkillTemplate extends AbstractTemplate {
|
||||
/**
|
||||
* The skill id
|
||||
*/
|
||||
@XmlAttribute(name = "id", required = true)
|
||||
@XmlJavaTypeAdapter(value = SkillTemplateIDAdapter.class)
|
||||
protected SkillTemplateID id;
|
||||
/**
|
||||
* The skill name
|
||||
*/
|
||||
@XmlAttribute(name = "name", required = true)
|
||||
protected String name;
|
||||
/**
|
||||
* The skill delay
|
||||
*/
|
||||
@XmlAttribute(name = "delay")
|
||||
protected int delay;
|
||||
/**
|
||||
* The skill cooldown
|
||||
*/
|
||||
@XmlAttribute(name = "cooldown")
|
||||
protected int cooldown;
|
||||
|
||||
@@ -59,6 +71,9 @@ public class SkillTemplate extends AbstractTemplate {
|
||||
*/
|
||||
protected int maximumLevel = 1;
|
||||
|
||||
/**
|
||||
* The skill effects
|
||||
*/
|
||||
@XmlElements({ @XmlElement(name = "teleport", type = TeleportEffectTemplate.class) })
|
||||
protected EffectTemplate[] effects;
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ import javax.xml.bind.annotation.XmlType;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "CharacterClassType")
|
||||
@SuppressWarnings("javadoc")
|
||||
public enum CharacterClass {
|
||||
/**
|
||||
* Human fighter
|
||||
|
||||
@@ -8,6 +8,7 @@ import javax.xml.bind.annotation.XmlType;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "CharacterRaceType")
|
||||
@SuppressWarnings("javadoc")
|
||||
public enum CharacterRace {
|
||||
HUMAN(0x00), ELF(0x01), DARK_ELF(0x02), ORC(0x03), DWARF(0x04), KAMAEL(0x05);
|
||||
|
||||
|
||||
@@ -39,129 +39,291 @@ import com.l2jserver.util.jaxb.CharacterTemplateIDAdapter;
|
||||
@XmlType(namespace = "http://schemas.l2jserver2.com/character", name = "CharacterType")
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class CharacterTemplate extends ActorTemplate<L2Character> {
|
||||
/**
|
||||
* The character templat eid
|
||||
*/
|
||||
@XmlJavaTypeAdapter(CharacterTemplateIDAdapter.class)
|
||||
@XmlAttribute(name = "class", required = true)
|
||||
protected CharacterTemplateID id = null;
|
||||
|
||||
/**
|
||||
* The character stats
|
||||
*/
|
||||
@XmlElement(name = "stats", required = true)
|
||||
protected CharacterStatsMetadata stats = null;
|
||||
|
||||
/**
|
||||
* Defines the character stats
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "CharacterStatsType")
|
||||
protected static class CharacterStatsMetadata {
|
||||
/**
|
||||
* The character level
|
||||
*/
|
||||
@XmlAttribute(name = "level", required = true)
|
||||
protected int level = 0;
|
||||
/**
|
||||
* Whether the character is an crafter or not
|
||||
*/
|
||||
@XmlAttribute(name = "crafter", required = false)
|
||||
protected boolean crafter = false;
|
||||
|
||||
/**
|
||||
* The character HP descriptor
|
||||
*/
|
||||
@XmlElement(name = "hp", required = true)
|
||||
protected Stat hp = null;
|
||||
/**
|
||||
* The character MP descriptor
|
||||
*/
|
||||
@XmlElement(name = "mp", required = true)
|
||||
protected Stat mp = null;
|
||||
/**
|
||||
* The character CP descriptor
|
||||
*/
|
||||
@XmlElement(name = "cp", required = true)
|
||||
protected Stat cp = null;
|
||||
|
||||
/**
|
||||
* Describes an character stat (HP, MP or CP)
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "")
|
||||
protected static class Stat {
|
||||
/**
|
||||
* The base value
|
||||
*/
|
||||
@XmlAttribute(name = "base", required = true)
|
||||
protected double base = 0;
|
||||
/**
|
||||
* The value modified
|
||||
*/
|
||||
@XmlAttribute(name = "modifier", required = true)
|
||||
protected double modifier = 0;
|
||||
/**
|
||||
* The value add
|
||||
*/
|
||||
@XmlAttribute(name = "add", required = true)
|
||||
protected double add = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The character attack data
|
||||
*/
|
||||
@XmlElement(name = "attack", required = true)
|
||||
protected AttackMetadata attack = null;
|
||||
|
||||
/**
|
||||
* Defines the character attack data
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "CharacterAttackType")
|
||||
protected static class AttackMetadata {
|
||||
/**
|
||||
* The character evasion
|
||||
*/
|
||||
@XmlAttribute(name = "evasion", required = true)
|
||||
protected int evasion = 0;
|
||||
/**
|
||||
* The character critical chance
|
||||
*/
|
||||
@XmlAttribute(name = "critical", required = true)
|
||||
protected int critical = 0;
|
||||
/**
|
||||
* The character accuracy
|
||||
*/
|
||||
@XmlAttribute(name = "accuracy", required = true)
|
||||
protected int accuracy = 0;
|
||||
|
||||
/**
|
||||
* The character physical attack data
|
||||
*/
|
||||
@XmlElement(name = "physical", required = true)
|
||||
protected AttackValueMetadata physical = null;
|
||||
/**
|
||||
* The character magical attack data
|
||||
*/
|
||||
@XmlElement(name = "magical", required = true)
|
||||
protected AttackValueMetadata magical = null;
|
||||
|
||||
/**
|
||||
* Defines an attack attribute
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "")
|
||||
protected static class AttackValueMetadata {
|
||||
/**
|
||||
* The damage dealt
|
||||
*/
|
||||
@XmlAttribute(name = "damage", required = true)
|
||||
protected double damage = 0;
|
||||
/**
|
||||
* The attack speed
|
||||
*/
|
||||
@XmlAttribute(name = "speed", required = true)
|
||||
protected double speed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The character defense data
|
||||
*/
|
||||
@XmlElement(name = "defense", required = true)
|
||||
protected DefenseMetadata defense = null;
|
||||
|
||||
/**
|
||||
* Defines the character defense data
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "CharacterDefenseType")
|
||||
protected static class DefenseMetadata {
|
||||
/**
|
||||
* The character physical defense
|
||||
*/
|
||||
@XmlElement(name = "physical", required = true)
|
||||
protected DefenseValueMetadata physical = null;
|
||||
/**
|
||||
* The character magical defense
|
||||
*/
|
||||
@XmlElement(name = "magical", required = true)
|
||||
protected DefenseValueMetadata magical = null;
|
||||
|
||||
/**
|
||||
* Defines an defense attribute
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "")
|
||||
protected static class DefenseValueMetadata {
|
||||
/**
|
||||
* The defense value
|
||||
*/
|
||||
@XmlAttribute(name = "value", required = true)
|
||||
protected double value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The charatcer movement medatata
|
||||
*/
|
||||
@XmlElement(name = "move", required = true)
|
||||
protected MoveMetadata move = null;
|
||||
|
||||
/**
|
||||
* Defines the character movement
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
*/
|
||||
@XmlType(name = "CharacterMovementType")
|
||||
protected static class MoveMetadata {
|
||||
/**
|
||||
* The run speed
|
||||
*/
|
||||
@XmlAttribute(name = "run", required = true)
|
||||
protected double run = 0;
|
||||
/**
|
||||
* The walk speed
|
||||
*/
|
||||
@XmlAttribute(name = "walk", required = true)
|
||||
protected double walk = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The character base stats
|
||||
*/
|
||||
@XmlElement(name = "base", required = true)
|
||||
protected BaseMetadata base = null;
|
||||
|
||||
/**
|
||||
* Defines an character base stats
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "CharacterBaseStatsType")
|
||||
protected static class BaseMetadata {
|
||||
/**
|
||||
* The intelligence
|
||||
*/
|
||||
@XmlAttribute(name = "int", required = true)
|
||||
protected int intelligence = 0;
|
||||
/**
|
||||
* The strength
|
||||
*/
|
||||
@XmlAttribute(name = "str", required = true)
|
||||
protected int strength = 0;
|
||||
/**
|
||||
* The concentration
|
||||
*/
|
||||
@XmlAttribute(name = "con", required = true)
|
||||
protected int concentration = 0;
|
||||
/**
|
||||
* The mentality
|
||||
*/
|
||||
@XmlAttribute(name = "men", required = true)
|
||||
protected int mentality = 0;
|
||||
/**
|
||||
* The dexterity
|
||||
*/
|
||||
@XmlAttribute(name = "dex", required = true)
|
||||
protected int dexterity = 0;
|
||||
/**
|
||||
* The witness
|
||||
*/
|
||||
@XmlAttribute(name = "wit", required = true)
|
||||
protected int witness = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The character maximum load
|
||||
*/
|
||||
@XmlElement(name = "maxload", required = true)
|
||||
protected int maximumLoad = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The character collision data
|
||||
*/
|
||||
@XmlElement(name = "collision", required = true)
|
||||
protected CollitionMetadataContainer collision = null;
|
||||
|
||||
/**
|
||||
* Defines the character collision data
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "CharacterCollisionType")
|
||||
protected static class CollitionMetadataContainer {
|
||||
/**
|
||||
* Collision data for male characters
|
||||
*/
|
||||
@XmlElement(name = "male", required = true)
|
||||
protected CollisionMetadata male = null;
|
||||
|
||||
/**
|
||||
* Collision data for female characters
|
||||
*/
|
||||
@XmlElement(name = "female", required = true)
|
||||
protected CollisionMetadata female = null;
|
||||
|
||||
/**
|
||||
* Defines an collision data
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
*/
|
||||
@XmlType(name = "")
|
||||
protected static class CollisionMetadata {
|
||||
/**
|
||||
* The character radius
|
||||
*/
|
||||
@XmlAttribute(name = "radius", required = true)
|
||||
protected double radius = 0;
|
||||
/**
|
||||
* The character height
|
||||
*/
|
||||
@XmlAttribute(name = "heigth", required = true)
|
||||
protected double height = 0;
|
||||
}
|
||||
|
||||
@@ -36,10 +36,16 @@ import com.l2jserver.util.jaxb.EffectTemplateIDAdapter;
|
||||
@XmlType(name = "Effect")
|
||||
@XmlSeeAlso({ TeleportEffectTemplate.class })
|
||||
public abstract class EffectTemplate implements Template {
|
||||
/**
|
||||
* The effect template ID
|
||||
*/
|
||||
@XmlAttribute(name = "id")
|
||||
@XmlJavaTypeAdapter(EffectTemplateIDAdapter.class)
|
||||
protected EffectTemplateID id;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*/
|
||||
protected EffectTemplate() {
|
||||
this.id = null;
|
||||
}
|
||||
|
||||
@@ -39,12 +39,34 @@ import com.l2jserver.util.jaxb.CoordinateAdapter;
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "TeleportEffect")
|
||||
public class TeleportEffectTemplate extends EffectTemplate {
|
||||
/**
|
||||
* The teleportation type
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public enum SkillTeleportEffectLocation {
|
||||
TARGET, OFFSET_FROM_TARGET, POINT;
|
||||
/**
|
||||
* Teleports the caster to the current target
|
||||
*/
|
||||
TARGET,
|
||||
/**
|
||||
* Teleports the caster to an offset from the target
|
||||
*/
|
||||
OFFSET_FROM_TARGET,
|
||||
/**
|
||||
* Teleports the caster to an fixed point
|
||||
*/
|
||||
POINT;
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of teleportation
|
||||
*/
|
||||
@XmlAttribute(name = "type", required = false)
|
||||
private SkillTeleportEffectLocation type = SkillTeleportEffectLocation.TARGET;
|
||||
/**
|
||||
* The point (only of <code>type</code> is {@link SkillTeleportEffectLocation#POINT})
|
||||
*/
|
||||
@XmlElement(name = "point")
|
||||
@XmlJavaTypeAdapter(CoordinateAdapter.class)
|
||||
private Coordinate coordinate;
|
||||
|
||||
@@ -25,5 +25,24 @@ import javax.xml.bind.annotation.XmlType;
|
||||
*/
|
||||
@XmlType(name = "ArmorType")
|
||||
public enum ArmorType {
|
||||
NONE, LIGHT, HEAVY, MAGIC, SIGILO;
|
||||
/**
|
||||
* No armor type
|
||||
*/
|
||||
NONE,
|
||||
/**
|
||||
* Light armor type
|
||||
*/
|
||||
LIGHT,
|
||||
/**
|
||||
* Heavy armor type
|
||||
*/
|
||||
HEAVY,
|
||||
/**
|
||||
* Magic armor type
|
||||
*/
|
||||
MAGIC,
|
||||
/**
|
||||
* Unknown
|
||||
*/
|
||||
SIGILO;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,12 @@ package com.l2jserver.model.template.item;
|
||||
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
/**
|
||||
* The material the item is made off
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@SuppressWarnings("javadoc")
|
||||
@XmlType(name = "ItemMaterialType")
|
||||
public enum ItemMaterial {
|
||||
COTTON, WOOD, PAPER, FISH, ORIHARUKON, HORN, ADAMANTAITE, CHRYSOLITE, MITHRIL, COBWEB, RUNE_XP, CLOTH, SCALE_OF_DRAGON, BONE, GOLD, LEATHER, FINE_STEEL, SILVER, DYESTUFF, CRYSTAL, RUNE_REMOVE_PENALTY, STEEL, BRONZE, RUNE_SP, LIQUID, BLOOD_STEEL, DAMASCUS;
|
||||
|
||||
@@ -50,63 +50,148 @@ public class ItemTemplate extends AbstractTemplate {
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(ItemTemplate.class);
|
||||
|
||||
/**
|
||||
* The Item Template ID
|
||||
*/
|
||||
@XmlAttribute(name = "id", required = true)
|
||||
@XmlJavaTypeAdapter(ItemTemplateIDAdapter.class)
|
||||
protected ItemTemplateID id;
|
||||
|
||||
/**
|
||||
* The item name
|
||||
*/
|
||||
@XmlAttribute(name = "name", required = true)
|
||||
protected String name;
|
||||
/**
|
||||
* The item weight
|
||||
*/
|
||||
@XmlElement(name = "weight", required = true)
|
||||
protected int weight = 0;
|
||||
/**
|
||||
* The item price
|
||||
*/
|
||||
@XmlElement(name = "price", required = true)
|
||||
protected int price = 0;
|
||||
/**
|
||||
* The item icon
|
||||
*/
|
||||
@XmlElement(name = "icon", required = false)
|
||||
protected String icon;
|
||||
/**
|
||||
* The item effects
|
||||
*/
|
||||
@XmlElement(name = "effect", required = false)
|
||||
protected EffectContainer effect;
|
||||
|
||||
/**
|
||||
* Effect container for items
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "ItemEffectsType")
|
||||
private static class EffectContainer {
|
||||
/**
|
||||
* The effect type
|
||||
*/
|
||||
@XmlAttribute(name = "type", required = true)
|
||||
protected EffectType effect;
|
||||
}
|
||||
|
||||
/**
|
||||
* The item stats container
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "ItemStatsType")
|
||||
protected static class StatsContainer {
|
||||
/**
|
||||
* The weapon's physical damage
|
||||
*/
|
||||
@XmlElement(name = "physicalDamage", required = false)
|
||||
protected StatAttribute physicalDamage;
|
||||
/**
|
||||
* The weapons's magical damage
|
||||
*/
|
||||
@XmlElement(name = "magicalDamage", required = false)
|
||||
protected StatAttribute magicalDamage;
|
||||
/**
|
||||
* The weapon's critical chance
|
||||
*/
|
||||
@XmlElement(name = "criticalChance", required = false)
|
||||
protected StatAttribute criticalChance;
|
||||
/**
|
||||
* The weapon's physical attack speed
|
||||
*/
|
||||
@XmlElement(name = "physicalAttackSpeed", required = false)
|
||||
protected StatAttribute physicalAttackSpeed;
|
||||
}
|
||||
|
||||
/**
|
||||
* The item stats
|
||||
*/
|
||||
@XmlElement(name = "stats", required = false)
|
||||
protected StatsContainer stats;
|
||||
|
||||
/**
|
||||
* The item material
|
||||
*/
|
||||
@XmlElement(name = "material", required = true)
|
||||
protected ItemMaterial material;
|
||||
|
||||
/**
|
||||
* The item effect type
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "ItemEffectType")
|
||||
public enum EffectType {
|
||||
/**
|
||||
* The effect is applied immediately once used
|
||||
*/
|
||||
IMMEDIATE;
|
||||
}
|
||||
|
||||
/**
|
||||
* The item type
|
||||
*/
|
||||
protected ItemType itemType = ItemType.NONE;
|
||||
/**
|
||||
* The weapon type
|
||||
*/
|
||||
protected WeaponType weaponType = WeaponType.NONE;
|
||||
/**
|
||||
* The armor type
|
||||
*/
|
||||
protected ArmorType armorType = ArmorType.NONE;
|
||||
|
||||
/**
|
||||
* An item stat attribute
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "ItemAttributeType")
|
||||
public static class StatAttribute {
|
||||
/**
|
||||
* The set
|
||||
*/
|
||||
@XmlElement(name = "set", required = true)
|
||||
protected StatSet set;
|
||||
|
||||
/**
|
||||
* Defines an SET calculator function
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "")
|
||||
public static class StatSet {
|
||||
/**
|
||||
* The execution order
|
||||
*/
|
||||
@XmlAttribute(name = "order", required = true)
|
||||
protected int order;
|
||||
/**
|
||||
* The value to be set
|
||||
*/
|
||||
@XmlValue
|
||||
protected double value;
|
||||
|
||||
|
||||
@@ -128,8 +128,31 @@ public enum ItemType {
|
||||
/**
|
||||
* Bolt? unk.
|
||||
*/
|
||||
BOLT(26), SCRL_INC_ENCHANT_PROP_WP(27), SCRL_INC_ENCHANT_PROP_AM(28), ANCIENT_CRYSTAL_ENCHANT_WP(
|
||||
29), ANCIENT_CRYSTAL_ENCHANT_AM(30), RUNE_SELECT(31), RUNE(32);
|
||||
BOLT(26),
|
||||
/**
|
||||
* Scoll
|
||||
*/
|
||||
SCRL_INC_ENCHANT_PROP_WP(27),
|
||||
/**
|
||||
* Scroll
|
||||
*/
|
||||
SCRL_INC_ENCHANT_PROP_AM(28),
|
||||
/**
|
||||
* Ancient crystal enchant weapon
|
||||
*/
|
||||
ANCIENT_CRYSTAL_ENCHANT_WP(29),
|
||||
/**
|
||||
* Ancient crystal enchant armor
|
||||
*/
|
||||
ANCIENT_CRYSTAL_ENCHANT_AM(30),
|
||||
/**
|
||||
* Rune select
|
||||
*/
|
||||
RUNE_SELECT(31),
|
||||
/**
|
||||
* Rune
|
||||
*/
|
||||
RUNE(32);
|
||||
|
||||
/**
|
||||
* The packet id for this item type
|
||||
|
||||
@@ -22,6 +22,7 @@ import javax.xml.bind.annotation.XmlType;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "NPCRaceType")
|
||||
@SuppressWarnings("javadoc")
|
||||
public enum NPCRace {
|
||||
// character races
|
||||
HUMAN, ELVEN, DARKELVEN, ORC, DWARVEN, KAMAEL,
|
||||
|
||||
@@ -51,241 +51,539 @@ import com.l2jserver.util.jaxb.SkillTemplateIDAdapter;
|
||||
@XmlType(namespace = "http://schemas.l2jserver2.com/npc", name = "NPCType")
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class NPCTemplate extends ActorTemplate<NPC> {
|
||||
/**
|
||||
* The template ID
|
||||
*/
|
||||
@XmlAttribute(name = "id", required = true)
|
||||
@XmlJavaTypeAdapter(value = NPCTemplateIDAdapter.class)
|
||||
protected NPCTemplateID id = null;
|
||||
/**
|
||||
* The {@link NPC} controller class
|
||||
*/
|
||||
@XmlAttribute(name = "controller", required = true)
|
||||
protected Class<? extends NPCController> controller;
|
||||
|
||||
/**
|
||||
* The {@link NPC} information metadata
|
||||
*/
|
||||
@XmlElement(name = "info", required = true)
|
||||
protected NPCInformationMetadata info = null;
|
||||
|
||||
/**
|
||||
* The {@link NPC} information metadata model
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "NPCInfoType")
|
||||
protected static class NPCInformationMetadata {
|
||||
/**
|
||||
* The {@link NPC} name metadata
|
||||
*/
|
||||
@XmlElement(name = "name", required = false)
|
||||
public NPCNameMetadata nameMetadata = null;
|
||||
|
||||
/**
|
||||
* Defines the {@link NPC}'s name information
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "NPCNameType")
|
||||
protected static class NPCNameMetadata {
|
||||
/**
|
||||
* The {@link NPC} name
|
||||
*/
|
||||
@XmlValue
|
||||
protected String name = null;
|
||||
/**
|
||||
* Whether the {@link NPC} name should be sent to the client or not
|
||||
*/
|
||||
@XmlAttribute(name = "send")
|
||||
protected Boolean send = false;
|
||||
/**
|
||||
* Whether the name should be displayed on the client or not
|
||||
*/
|
||||
@XmlAttribute(name = "display")
|
||||
protected Boolean display = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link NPC} title metadata
|
||||
*/
|
||||
@XmlElement(name = "title", required = false)
|
||||
protected NPCTitleMetadata titleMetadata = null;
|
||||
|
||||
/**
|
||||
* Defines the {@link NPC}'s title information
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "NPCTitleType")
|
||||
protected static class NPCTitleMetadata {
|
||||
/**
|
||||
* The {@link NPC} title
|
||||
*/
|
||||
@XmlValue
|
||||
protected String title = null;
|
||||
/**
|
||||
* Whether the {@link NPC} title should be sent to the client or not
|
||||
*/
|
||||
@XmlAttribute(name = "send")
|
||||
protected Boolean send = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link NPC} level
|
||||
*/
|
||||
@XmlElement(name = "level", required = true)
|
||||
protected int level = 0;
|
||||
/**
|
||||
* The {@link NPC} race
|
||||
*/
|
||||
@XmlElement(name = "race", required = false)
|
||||
protected NPCRace race = NPCRace.NONE;
|
||||
/**
|
||||
* The {@link NPC} sex
|
||||
*/
|
||||
@XmlElement(name = "sex", required = false)
|
||||
protected ActorSex sex = null;
|
||||
|
||||
/**
|
||||
* Whether this {@link NPC} can be attacked or not
|
||||
*/
|
||||
@XmlAttribute(name = "attackable", required = false)
|
||||
protected boolean attackable = false;
|
||||
/**
|
||||
* Whether this {@link NPC} can be targeted or not
|
||||
*/
|
||||
@XmlAttribute(name = "targetable", required = false)
|
||||
protected boolean targetable = false;
|
||||
/**
|
||||
* Whether this {@link NPC} is aggressive
|
||||
*/
|
||||
@XmlAttribute(name = "aggressive", required = false)
|
||||
protected boolean aggressive = false;
|
||||
|
||||
/**
|
||||
* The {@link NPC} stats metadata, such as hp and mp
|
||||
*/
|
||||
@XmlElement(name = "stats", required = true)
|
||||
protected NPCStatsMetadata stats = null;
|
||||
|
||||
/**
|
||||
* Defines {@link NPC}'s stats, such as HP and MP
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
*/
|
||||
@XmlType(name = "NPCStatsType")
|
||||
protected static class NPCStatsMetadata {
|
||||
/**
|
||||
* The {@link NPC} maximum HP
|
||||
*/
|
||||
@XmlElement(name = "hp", required = true)
|
||||
protected Stat hp = null;
|
||||
/**
|
||||
* The {@link NPC} maximum MP
|
||||
*/
|
||||
@XmlElement(name = "mp", required = true)
|
||||
protected Stat mp = null;
|
||||
|
||||
/**
|
||||
* Defines an stat (HP or MP)
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "")
|
||||
protected static class Stat {
|
||||
/**
|
||||
* The maximum value
|
||||
*/
|
||||
@XmlAttribute(name = "max", required = true)
|
||||
protected double max = 0;
|
||||
/**
|
||||
* The regeneration speed
|
||||
*/
|
||||
@XmlAttribute(name = "regen", required = true)
|
||||
protected double regen = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link NPC} attack metadata
|
||||
*/
|
||||
@XmlElement(name = "attack", required = false)
|
||||
protected AttackMetadata attack = null;
|
||||
|
||||
/**
|
||||
* Defines {@link NPC}'s attacking metadata
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "NPCAttackType")
|
||||
protected static class AttackMetadata {
|
||||
/**
|
||||
* The {@link NPC}'s attack range
|
||||
*/
|
||||
@XmlAttribute(name = "range", required = true)
|
||||
protected int range = 0;
|
||||
/**
|
||||
* The {@link NPC}'s evasion
|
||||
*/
|
||||
@XmlAttribute(name = "evasion", required = true)
|
||||
protected int evasion = 0;
|
||||
/**
|
||||
* The {@link NPC}'s attack critical chance
|
||||
*/
|
||||
@XmlAttribute(name = "critical", required = true)
|
||||
protected int critical = 0;
|
||||
|
||||
/**
|
||||
* The {@link NPC}'s attack physical damage
|
||||
*/
|
||||
@XmlElement(name = "physical", required = true)
|
||||
protected AttackValueMetadata physical = null;
|
||||
/**
|
||||
* The {@link NPC}'s attack magical damage
|
||||
*/
|
||||
@XmlElement(name = "magical", required = true)
|
||||
protected AttackValueMetadata magical = null;
|
||||
|
||||
/**
|
||||
* Defines an attack value
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "")
|
||||
protected static class AttackValueMetadata {
|
||||
/**
|
||||
* The damage dealt
|
||||
*/
|
||||
@XmlAttribute(name = "damage", required = true)
|
||||
protected double damage = 0;
|
||||
/**
|
||||
* The attacking speed
|
||||
*/
|
||||
@XmlAttribute(name = "speed", required = true)
|
||||
protected double speed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link NPC} defense metadata
|
||||
*/
|
||||
@XmlElement(name = "defense", required = false)
|
||||
protected DefenseMetadata defense = null;
|
||||
|
||||
/**
|
||||
* Defines {@link NPC}'s defensive metadata
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "NPCDefenseType")
|
||||
protected static class DefenseMetadata {
|
||||
/**
|
||||
* The {@link NPC}'s physical defense
|
||||
*/
|
||||
@XmlElement(name = "physical", required = true)
|
||||
protected DefenseValueMetadata physical = null;
|
||||
/**
|
||||
* The {@link NPC}'s magical defense
|
||||
*/
|
||||
@XmlElement(name = "magical", required = true)
|
||||
protected DefenseValueMetadata magical = null;
|
||||
|
||||
/**
|
||||
* Defines an defense value
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "")
|
||||
protected static class DefenseValueMetadata {
|
||||
/**
|
||||
* The defense value
|
||||
*/
|
||||
@XmlAttribute(name = "value", required = true)
|
||||
protected double value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link NPC} movement data
|
||||
*/
|
||||
@XmlElement(name = "move", required = false)
|
||||
protected MoveMetadata move = null;
|
||||
|
||||
/**
|
||||
* Defines {@link NPC} movement data
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "NPCMovementType")
|
||||
protected static class MoveMetadata {
|
||||
/**
|
||||
* The run speed
|
||||
*/
|
||||
@XmlAttribute(name = "run", required = true)
|
||||
protected double run = 0;
|
||||
/**
|
||||
* The walk speed
|
||||
*/
|
||||
@XmlAttribute(name = "walk", required = true)
|
||||
protected double walk = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link NPC} base stats
|
||||
*/
|
||||
@XmlElement(name = "base", required = true)
|
||||
public BaseMetadata base = null;
|
||||
|
||||
/**
|
||||
* Defines all base stats for {@link NPC} instances
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "NPCBaseStatsType")
|
||||
protected static class BaseMetadata {
|
||||
/**
|
||||
* The {@link NPC} intelligence
|
||||
*/
|
||||
@XmlAttribute(name = "int", required = true)
|
||||
protected int intelligence = 0;
|
||||
/**
|
||||
* The {@link NPC} strength
|
||||
*/
|
||||
@XmlAttribute(name = "str", required = true)
|
||||
protected int strength = 0;
|
||||
/**
|
||||
* The {@link NPC} concentration
|
||||
*/
|
||||
@XmlAttribute(name = "con", required = true)
|
||||
protected int concentration = 0;
|
||||
/**
|
||||
* The {@link NPC} mentality
|
||||
*/
|
||||
@XmlAttribute(name = "men", required = true)
|
||||
protected int mentality = 0;
|
||||
/**
|
||||
* The {@link NPC} dexterity
|
||||
*/
|
||||
@XmlAttribute(name = "dex", required = true)
|
||||
protected int dexterity = 0;
|
||||
/**
|
||||
* The {@link NPC} witness
|
||||
*/
|
||||
@XmlAttribute(name = "wit", required = true)
|
||||
protected int witness = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link NPC} experience
|
||||
*/
|
||||
@XmlElement(name = "experience", required = true)
|
||||
protected long experience = 0;
|
||||
/**
|
||||
* The {@link NPC} SP
|
||||
*/
|
||||
@XmlElement(name = "sp", required = true)
|
||||
protected int sp = 0;
|
||||
|
||||
/**
|
||||
* The {@link NPC} holding items
|
||||
*/
|
||||
@XmlElement(name = "item", required = false)
|
||||
protected ItemMetadata item = null;
|
||||
|
||||
/**
|
||||
* Describes what items the {@link NPC} is holding on its hand
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "NPCItemsType")
|
||||
protected static class ItemMetadata {
|
||||
/**
|
||||
* The {@link ItemTemplateID} on {@link NPC}'s right hand
|
||||
*/
|
||||
@XmlAttribute(name = "righthand", required = false)
|
||||
@XmlJavaTypeAdapter(value = ItemTemplateIDAdapter.class)
|
||||
protected ItemTemplateID rightHand = null;
|
||||
/**
|
||||
* The {@link ItemTemplateID} on {@link NPC}'s left hand
|
||||
*/
|
||||
@XmlAttribute(name = "lefthand", required = false)
|
||||
@XmlJavaTypeAdapter(value = ItemTemplateIDAdapter.class)
|
||||
protected ItemTemplateID leftHand = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link NPC} collision data
|
||||
*/
|
||||
@XmlElement(name = "collision", required = false)
|
||||
protected CollisionMetadata collision = null;
|
||||
|
||||
/**
|
||||
* Defines the {@link NPC} dimensions used for collisions
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "NPCCollisionType")
|
||||
protected static class CollisionMetadata {
|
||||
/**
|
||||
* The {@link NPC} radius
|
||||
*/
|
||||
@XmlAttribute(name = "radius", required = true)
|
||||
protected double radius = 0;
|
||||
/**
|
||||
* The {@link NPC} height
|
||||
*/
|
||||
@XmlAttribute(name = "heigth", required = true)
|
||||
protected double height = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link NPC} AI data
|
||||
*/
|
||||
@XmlElement(name = "ai", required = false)
|
||||
protected AIMetadata ai = null;
|
||||
|
||||
/**
|
||||
* Describes the {@link NPC} ai data
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "NPCAIType")
|
||||
protected static class AIMetadata {
|
||||
/**
|
||||
* The ai script to be used
|
||||
*/
|
||||
@XmlAttribute(name = "script", required = true)
|
||||
protected String script = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains all {@link NPC} conversation HTML messages
|
||||
*/
|
||||
@XmlElement(name = "talk", required = false)
|
||||
protected TalkMetadata talk = null;
|
||||
|
||||
/**
|
||||
* Describes {@link NPC} talking capability as HTML messages
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "NPCTalkType")
|
||||
protected static class TalkMetadata {
|
||||
/**
|
||||
* The default chat message
|
||||
*/
|
||||
@XmlAttribute(name = "default", required = true)
|
||||
protected String defaultChat = null;
|
||||
|
||||
/**
|
||||
* The list of {@link Chat} available
|
||||
*/
|
||||
@XmlElement(name = "chat", required = true)
|
||||
protected List<Chat> chats = null;
|
||||
|
||||
/**
|
||||
* Describes an "chat" message (an HTML page)
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "")
|
||||
public static class Chat {
|
||||
/**
|
||||
* The chat ID
|
||||
*/
|
||||
@XmlAttribute(name = "id", required = true)
|
||||
protected String id = null;
|
||||
/**
|
||||
* The message content
|
||||
*/
|
||||
@XmlValue
|
||||
protected String html = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link NPC} drop list
|
||||
*/
|
||||
@XmlElementWrapper(name = "droplist", required = false)
|
||||
@XmlElement(name = "item", required = true)
|
||||
protected List<DropItemMetadata> droplist = null;
|
||||
|
||||
/**
|
||||
* Describes {@link NPC} dropping when it is killed
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "NPCDropType")
|
||||
protected static class DropItemMetadata {
|
||||
/**
|
||||
* The item dropped
|
||||
*/
|
||||
@XmlAttribute(name = "id", required = true)
|
||||
@XmlJavaTypeAdapter(value = ItemTemplateIDAdapter.class)
|
||||
protected ItemTemplateID item = null;
|
||||
/**
|
||||
* The minimum amount of items dropped
|
||||
*/
|
||||
@XmlAttribute(name = "min", required = true)
|
||||
protected int min = 0;
|
||||
/**
|
||||
* The maximum amount of item dropped
|
||||
*/
|
||||
@XmlAttribute(name = "max", required = true)
|
||||
protected int max = 0;
|
||||
|
||||
/**
|
||||
* The drop category
|
||||
*/
|
||||
@XmlAttribute(name = "category", required = true)
|
||||
protected DropCategory category = null;
|
||||
|
||||
/**
|
||||
* The drop category
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@SuppressWarnings("javadoc")
|
||||
@XmlType(name = "NPCDropCategoryType")
|
||||
public enum DropCategory {
|
||||
DROP, SPOIL, UNK_1, UNK_2, UNK_3, UNK_4, UNK_5, UNK_6, UNK_7, UNK_8, UNK_9, UNK_10, UNK_11, UNK_12, UNK_13, UNK_14, UNK_15, UNK_16, UNK_17, UNK_18, UNK_19, UNK_20, UNK_21, UNK_22, UNK_23, UNK_24, UNK_25, UNK_26, UNK_27, UNK_28, UNK_29, UNK_30, UNK_31, UNK_32, UNK_33, UNK_34, UNK_35, UNK_36, UNK_100, UNK_101, UNK_102, UNK_200;
|
||||
}
|
||||
|
||||
/**
|
||||
* The drop chance
|
||||
*/
|
||||
@XmlAttribute(name = "chance", required = true)
|
||||
protected int chance = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of all available {@link NPC} skills
|
||||
*/
|
||||
@XmlElementWrapper(name = "skills", required = false)
|
||||
@XmlElement(name = "skill", required = true)
|
||||
protected List<SkillMetadata> skills = null;
|
||||
|
||||
/**
|
||||
* Describes an {@link NPC} skill
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "NPCSkillType")
|
||||
protected static class SkillMetadata {
|
||||
/**
|
||||
* The skill ID
|
||||
*/
|
||||
@XmlAttribute(name = "id", required = true)
|
||||
@XmlJavaTypeAdapter(value = SkillTemplateIDAdapter.class)
|
||||
protected SkillTemplateID skill = null;
|
||||
/**
|
||||
* The skill level
|
||||
*/
|
||||
@XmlAttribute(name = "level", required = true)
|
||||
protected int level = 0;
|
||||
}
|
||||
@@ -321,6 +619,9 @@ public class NPCTemplate extends ActorTemplate<NPC> {
|
||||
return controller;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link NPC} name
|
||||
*/
|
||||
public String getName() {
|
||||
if (info == null)
|
||||
return null;
|
||||
@@ -329,6 +630,9 @@ public class NPCTemplate extends ActorTemplate<NPC> {
|
||||
return info.nameMetadata.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the {@link NPC} name should be sent to the client
|
||||
*/
|
||||
public boolean getSendName() {
|
||||
if (info == null)
|
||||
return false;
|
||||
@@ -337,6 +641,9 @@ public class NPCTemplate extends ActorTemplate<NPC> {
|
||||
return info.nameMetadata.send;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the {@link NPC} name should be displayed on the client
|
||||
*/
|
||||
public boolean getDisplayName() {
|
||||
if (info == null)
|
||||
return false;
|
||||
@@ -345,6 +652,9 @@ public class NPCTemplate extends ActorTemplate<NPC> {
|
||||
return info.nameMetadata.display;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the npc title (if any)
|
||||
*/
|
||||
public String getTitle() {
|
||||
if (info == null)
|
||||
return null;
|
||||
@@ -353,6 +663,9 @@ public class NPCTemplate extends ActorTemplate<NPC> {
|
||||
return info.titleMetadata.title;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return if the {@link NPC} title should be sent to the client
|
||||
*/
|
||||
public boolean getSendTitle() {
|
||||
if (info == null)
|
||||
return false;
|
||||
@@ -433,6 +746,9 @@ public class NPCTemplate extends ActorTemplate<NPC> {
|
||||
return info.sp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link NPC}'s maximum HP
|
||||
*/
|
||||
public double getMaximumHP() {
|
||||
if (info == null)
|
||||
return 0;
|
||||
@@ -443,6 +759,9 @@ public class NPCTemplate extends ActorTemplate<NPC> {
|
||||
return info.stats.hp.max;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link NPC}'s maximum HP regeneration
|
||||
*/
|
||||
public double getHPRegeneration() {
|
||||
if (info == null)
|
||||
return 0;
|
||||
@@ -453,6 +772,9 @@ public class NPCTemplate extends ActorTemplate<NPC> {
|
||||
return info.stats.hp.regen;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link NPC}'s maximum MP
|
||||
*/
|
||||
public double getMaximumMP() {
|
||||
if (info == null)
|
||||
return 0;
|
||||
@@ -463,6 +785,9 @@ public class NPCTemplate extends ActorTemplate<NPC> {
|
||||
return info.stats.mp.max;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link NPC}'s maximum MP regeneration
|
||||
*/
|
||||
public double getMPRegeneration() {
|
||||
if (info == null)
|
||||
return 0;
|
||||
@@ -602,6 +927,9 @@ public class NPCTemplate extends ActorTemplate<NPC> {
|
||||
return info.stats.attack.magical.speed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link NPC}'s run speed
|
||||
*/
|
||||
public double getRunSpeed() {
|
||||
if (info == null)
|
||||
return 0;
|
||||
@@ -612,6 +940,9 @@ public class NPCTemplate extends ActorTemplate<NPC> {
|
||||
return info.stats.move.run;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link NPC}'s walk speed
|
||||
*/
|
||||
public double getWalkSpeed() {
|
||||
if (info == null)
|
||||
return 0;
|
||||
@@ -700,6 +1031,9 @@ public class NPCTemplate extends ActorTemplate<NPC> {
|
||||
return info.stats.base.witness;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the item on {@link NPC}'s right hand
|
||||
*/
|
||||
public ItemTemplateID getRightHand() {
|
||||
if (info == null)
|
||||
return null;
|
||||
@@ -708,6 +1042,9 @@ public class NPCTemplate extends ActorTemplate<NPC> {
|
||||
return info.item.rightHand;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the item on {@link NPC}'s left hand
|
||||
*/
|
||||
public ItemTemplateID getLeftHand() {
|
||||
if (info == null)
|
||||
return null;
|
||||
@@ -716,6 +1053,9 @@ public class NPCTemplate extends ActorTemplate<NPC> {
|
||||
return info.item.leftHand;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link NPC}'s collision radius
|
||||
*/
|
||||
public double getCollisionRadius() {
|
||||
if (info == null)
|
||||
return 0;
|
||||
@@ -724,6 +1064,9 @@ public class NPCTemplate extends ActorTemplate<NPC> {
|
||||
return info.collision.radius;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link NPC}'s collision height
|
||||
*/
|
||||
public double getCollisionHeight() {
|
||||
if (info == null)
|
||||
return 0;
|
||||
@@ -732,12 +1075,20 @@ public class NPCTemplate extends ActorTemplate<NPC> {
|
||||
return info.collision.height;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link NPC}'s AI script name
|
||||
*/
|
||||
public String getAIScriptName() {
|
||||
if (ai == null)
|
||||
return null;
|
||||
return ai.script;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* the chat ID
|
||||
* @return the {@link NPC}'s HTML chat by ID
|
||||
*/
|
||||
public String getHTML(String id) {
|
||||
if (talk == null)
|
||||
return null;
|
||||
@@ -750,6 +1101,9 @@ public class NPCTemplate extends ActorTemplate<NPC> {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link NPC}'s default chat, if any.
|
||||
*/
|
||||
public String getDefaultHTML() {
|
||||
if (talk == null)
|
||||
return null;
|
||||
|
||||
@@ -44,28 +44,54 @@ import com.l2jserver.util.jaxb.TeleportationTemplateIDAdapter;
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(namespace = "http://schemas.l2jserver2.com/teleport", name = "TeleportType")
|
||||
public class TeleportationTemplate extends AbstractTemplate {
|
||||
/**
|
||||
* The teleportation template ID
|
||||
*/
|
||||
@XmlAttribute(name = "id")
|
||||
@XmlJavaTypeAdapter(TeleportationTemplateIDAdapter.class)
|
||||
protected TeleportationTemplateID id;
|
||||
/**
|
||||
* The teleportation name
|
||||
*/
|
||||
@XmlAttribute(name = "name")
|
||||
protected String name;
|
||||
|
||||
/**
|
||||
* The teleportation cost item id
|
||||
*/
|
||||
@XmlAttribute(name = "item", required = false)
|
||||
@XmlJavaTypeAdapter(ItemTemplateIDAdapter.class)
|
||||
protected ItemTemplateID itemTemplateID;
|
||||
/**
|
||||
* The amount of items decreased
|
||||
*/
|
||||
@XmlAttribute(name = "price", required = true)
|
||||
protected int price;
|
||||
|
||||
/**
|
||||
* The teleportation point
|
||||
*/
|
||||
@XmlElement(name = "point", required = false)
|
||||
@XmlJavaTypeAdapter(CoordinateAdapter.class)
|
||||
protected Coordinate coordinate;
|
||||
|
||||
/**
|
||||
* The teleportation restrictions
|
||||
*/
|
||||
@XmlElementWrapper(name = "restrictions", required = false)
|
||||
@XmlElement(name = "restriction", required = true)
|
||||
protected List<TeleportRestriction> restrictions;
|
||||
|
||||
/**
|
||||
* Defines an teleport restriction
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@XmlType(name = "TeleportRestrictionType")
|
||||
public enum TeleportRestriction {
|
||||
/**
|
||||
* Only nobles can use this teleport
|
||||
*/
|
||||
NOBLE;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.l2jserver.model.world.Actor;
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@SuppressWarnings("javadoc")
|
||||
public enum ActorExperience {
|
||||
/**
|
||||
* This is an unreachable level!
|
||||
|
||||
@@ -31,9 +31,21 @@ import com.l2jserver.model.world.Actor;
|
||||
*/
|
||||
public abstract class AbstractEffect<T extends EffectTemplate> implements
|
||||
Effect {
|
||||
/**
|
||||
* The effect template
|
||||
*/
|
||||
protected final T template;
|
||||
/**
|
||||
* The actor that the effect is applied to
|
||||
*/
|
||||
protected final Actor actor;
|
||||
|
||||
/**
|
||||
* @param template
|
||||
* the effect template
|
||||
* @param actor
|
||||
* the actor that the effect is applied to
|
||||
*/
|
||||
public AbstractEffect(T template, Actor actor) {
|
||||
this.template = template;
|
||||
this.actor = actor;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user