1
0
mirror of https://github.com/Rogiel/l2jserver2 synced 2025-12-05 23:22:47 +00:00

Implements character service configuration

This commit is contained in:
2011-12-29 02:27:42 -02:00
parent c5911ea884
commit f2cf139d34
18 changed files with 566 additions and 23 deletions

View File

@@ -50,6 +50,22 @@ public class ArrayUtils {
values.add(item); values.add(item);
} }
} }
return (T[]) Arrays.copyOf(values.toArray(), values.size(), array.getClass()); return (T[]) Arrays.copyOf(values.toArray(), values.size(),
array.getClass());
}
/**
* Searches for the <code>expected</code> item to be in the
* <code>array</code>.
*
* @param array
* the array to search in
* @param expected
* the item to be looked in the array
* @return <code>true</code> if the item exists, <code>false</code>
* otherwise
*/
public final static <T> boolean contains(T[] array, T expected) {
return Arrays.binarySearch(array, expected) >= 0;
} }
} }

View File

@@ -22,6 +22,7 @@ import java.net.URI;
import java.net.URL; import java.net.URL;
import java.nio.file.Path; import java.nio.file.Path;
import com.l2jserver.util.transformer.impl.ArrayTransformer;
import com.l2jserver.util.transformer.impl.BooleanTransformer; import com.l2jserver.util.transformer.impl.BooleanTransformer;
import com.l2jserver.util.transformer.impl.ByteTransformer; import com.l2jserver.util.transformer.impl.ByteTransformer;
import com.l2jserver.util.transformer.impl.ClassTransformer; import com.l2jserver.util.transformer.impl.ClassTransformer;
@@ -34,6 +35,7 @@ import com.l2jserver.util.transformer.impl.IntegerTransformer;
import com.l2jserver.util.transformer.impl.LongTransformer; import com.l2jserver.util.transformer.impl.LongTransformer;
import com.l2jserver.util.transformer.impl.PathTransformer; import com.l2jserver.util.transformer.impl.PathTransformer;
import com.l2jserver.util.transformer.impl.ShortTransformer; import com.l2jserver.util.transformer.impl.ShortTransformer;
import com.l2jserver.util.transformer.impl.StringTransformer;
import com.l2jserver.util.transformer.impl.URITransformer; import com.l2jserver.util.transformer.impl.URITransformer;
import com.l2jserver.util.transformer.impl.URLTransformer; import com.l2jserver.util.transformer.impl.URLTransformer;
@@ -78,9 +80,12 @@ public class TransformerFactory {
return URLTransformer.SHARED_INSTANCE; return URLTransformer.SHARED_INSTANCE;
} else if (type == Path.class) { } else if (type == Path.class) {
return PathTransformer.SHARED_INSTANCE; return PathTransformer.SHARED_INSTANCE;
} else if(type.isEnum()) { } else if (type.isEnum()) {
return EnumTransformer.SHARED_INSTANCE; return EnumTransformer.SHARED_INSTANCE;
} } else if(type.isArray()) {
return ArrayTransformer.SHARED_INSTANCE;
} else if (type == String.class)
return StringTransformer.SHARED_INSTANCE;
return null; return null;
} }
} }

View File

@@ -0,0 +1,72 @@
/*
* 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.util.transformer.impl;
import java.lang.reflect.Array;
import org.apache.commons.lang3.StringUtils;
import com.l2jserver.util.transformer.Transformer;
import com.l2jserver.util.transformer.TransformerFactory;
/**
* Transform an {@link Array} into an string.
* <p>
* <b>Important note</b>: Array elements are by an <code>|</code>.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
* @param <T>
* the array component type that this tranformer transforms
*/
public class ArrayTransformer<T> implements Transformer<T[]> {
/**
* This transformer shared instance
*/
@SuppressWarnings("rawtypes")
public static final ArrayTransformer<?> SHARED_INSTANCE = new ArrayTransformer();
@Override
@SuppressWarnings("unchecked")
public String transform(Class<? extends T[]> type, T[] value) {
final Transformer<T> transformer = (Transformer<T>) TransformerFactory
.getTransfromer(type.getComponentType());
final String[] values = new String[value.length];
int i = 0;
for (final T item : value) {
values[i++] = transformer.transform(
(Class<? extends T>) type.getComponentType(), item);
}
return StringUtils.join(values, '|');
}
@Override
@SuppressWarnings("unchecked")
public T[] untransform(Class<? extends T[]> type, String stringValue) {
final Transformer<T> transformer = (Transformer<T>) TransformerFactory
.getTransfromer(type.getComponentType());
final String[] stringValues = StringUtils.split(stringValue, '|');
final T[] values = (T[]) Array.newInstance(type.getComponentType(),
stringValues.length);
int i = 0;
for (final String value : stringValues) {
values[i++] = transformer.untransform(
(Class<? extends T>) type.getComponentType(), value);
}
return values;
}
}

View File

@@ -0,0 +1,42 @@
/*
* 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.util.transformer.impl;
import com.l2jserver.util.transformer.Transformer;
/**
* This tranformer does nothing!
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class StringTransformer implements Transformer<String> {
/**
* This transformer shared instance
*/
public static final StringTransformer SHARED_INSTANCE = new StringTransformer();
@Override
public String transform(Class<? extends String> type, String value) {
return value;
}
@Override
public String untransform(Class<? extends String> type, String value) {
return value;
}
}

View File

@@ -0,0 +1,94 @@
/*
* 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.util.transformer.impl;
import org.junit.Assert;
import org.junit.Test;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
*/
public class ArrayTransformerTest {
/**
* An Integer[] array as an string
*/
private static final String INT_ARRAY_STRING = "1|2|3";
/**
* An Integer[] array
*/
private static final Integer[] INT_ARRAY = new Integer[] { 1, 2, 3 };
/**
* An String[] array as an string
*/
private static final String STRING_ARRAY_STRING = "test1|test2|test3";
/**
* An String[] array
*/
private static final String[] STRING_ARRAY = new String[] { "test1",
"test2", "test3" };
/**
* An Class[] array as an string
*/
private static final String CLASS_ARRAY_STRING = "java.lang.Object|java.lang.Integer|java.lang.Long";
/**
* An Class[] array
*/
private static final Class<?>[] CLASS_ARRAY = new Class<?>[] {
Object.class, Integer.class, Long.class };
/**
* Tests transforming an {@link Integer} array
*/
@Test
public void testIntegerTransforming() {
final ArrayTransformer<Integer> transformer = new ArrayTransformer<Integer>();
Assert.assertEquals(INT_ARRAY_STRING,
transformer.transform(Integer[].class, INT_ARRAY));
Assert.assertArrayEquals(INT_ARRAY,
transformer.untransform(Integer[].class, INT_ARRAY_STRING));
}
/**
* Tests transforming an {@link String} array
*/
@Test
public void testStringTransforming() {
final ArrayTransformer<String> transformer = new ArrayTransformer<String>();
Assert.assertEquals(STRING_ARRAY_STRING,
transformer.transform(String[].class, STRING_ARRAY));
Assert.assertArrayEquals(STRING_ARRAY,
transformer.untransform(String[].class, STRING_ARRAY_STRING));
}
/**
* Tests transforming an {@link Class} array
*/
@Test
@SuppressWarnings("unchecked")
public void testClassTransforming() {
final ArrayTransformer<Class<?>> transformer = new ArrayTransformer<Class<?>>();
Assert.assertEquals(CLASS_ARRAY_STRING, transformer.transform(
(Class<? extends Class<?>[]>) Class[].class, CLASS_ARRAY));
Assert.assertArrayEquals(CLASS_ARRAY, transformer
.untransform((Class<? extends Class<?>[]>) Class[].class,
CLASS_ARRAY_STRING));
}
}

View File

@@ -88,7 +88,14 @@
<service interface="com.l2jserver.service.game.spawn.SpawnService" <service interface="com.l2jserver.service.game.spawn.SpawnService"
implementation="com.l2jserver.service.game.spawn.SpawnServiceImpl" /> implementation="com.l2jserver.service.game.spawn.SpawnServiceImpl" />
<service interface="com.l2jserver.service.game.character.CharacterService" <service interface="com.l2jserver.service.game.character.CharacterService"
implementation="com.l2jserver.service.game.character.CharacterServiceImpl" /> implementation="com.l2jserver.service.game.character.CharacterServiceImpl">
<!-- Defines the restrictions for account creation -->
<creation allow="true" allowed-races="HUMAN|ELF|DARK_ELF|ORC|DWARF|KAMAEL"
allowed-genders="MALE|FEMALE">
<!-- The maximum amount of characters per account -->
<limits max-per-account="8" />
</creation>
</service>
<service interface="com.l2jserver.service.game.character.ShortcutService" <service interface="com.l2jserver.service.game.character.ShortcutService"
implementation="com.l2jserver.service.game.character.ShortcutServiceImpl" /> implementation="com.l2jserver.service.game.character.ShortcutServiceImpl" />
<service interface="com.l2jserver.service.game.AttackService" <service interface="com.l2jserver.service.game.AttackService"
@@ -99,7 +106,8 @@
implementation="com.l2jserver.service.game.item.ItemServiceImpl"> implementation="com.l2jserver.service.game.item.ItemServiceImpl">
<!-- Whether drops are persisted in the database. Valid modes are: --> <!-- Whether drops are persisted in the database. Valid modes are: -->
<!-- ALL - All types of drops are stored into the database --> <!-- ALL - All types of drops are stored into the database -->
<!-- CHARACTER_ONLY - Only items dropped by characters are stored in the database --> <!-- CHARACTER_ONLY - Only items dropped by characters are stored in the
database -->
<!-- NONE - None of the dropped items are saved into the database --> <!-- NONE - None of the dropped items are saved into the database -->
<drop persistent="ALL" /> <drop persistent="ALL" />
</service> </service>

View File

@@ -109,7 +109,14 @@
<service interface="com.l2jserver.service.game.spawn.SpawnService" <service interface="com.l2jserver.service.game.spawn.SpawnService"
implementation="com.l2jserver.service.game.spawn.SpawnServiceImpl" /> implementation="com.l2jserver.service.game.spawn.SpawnServiceImpl" />
<service interface="com.l2jserver.service.game.character.CharacterService" <service interface="com.l2jserver.service.game.character.CharacterService"
implementation="com.l2jserver.service.game.character.CharacterServiceImpl" /> implementation="com.l2jserver.service.game.character.CharacterServiceImpl">
<!-- Defines the restrictions for account creation -->
<creation allow="true" allowed-races="HUMAN|ELF|DARK_ELF|ORC|DWARF|KAMAEL"
allowed-genders="MALE|FEMALE">
<!-- The maximum amount of characters per account -->
<limits max-per-account="8" />
</creation>
</service>
<service interface="com.l2jserver.service.game.character.ShortcutService" <service interface="com.l2jserver.service.game.character.ShortcutService"
implementation="com.l2jserver.service.game.character.ShortcutServiceImpl" /> implementation="com.l2jserver.service.game.character.ShortcutServiceImpl" />
<service interface="com.l2jserver.service.game.AttackService" <service interface="com.l2jserver.service.game.AttackService"

View File

@@ -16,6 +16,9 @@
*/ */
package com.l2jserver.game.net.packet; package com.l2jserver.game.net.packet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* An abstract {@link ClientPacket} * An abstract {@link ClientPacket}
* *
@@ -23,4 +26,8 @@ package com.l2jserver.game.net.packet;
* @see ClientPacket * @see ClientPacket
*/ */
public abstract class AbstractClientPacket implements ClientPacket { public abstract class AbstractClientPacket implements ClientPacket {
/**
* The packet {@link Logger} instance
*/
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
} }

View File

@@ -16,6 +16,9 @@
*/ */
package com.l2jserver.game.net.packet; package com.l2jserver.game.net.packet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* An abstract {@link ServerPacket} * An abstract {@link ServerPacket}
* *
@@ -23,6 +26,11 @@ package com.l2jserver.game.net.packet;
* @see ServerPacket * @see ServerPacket
*/ */
public abstract class AbstractServerPacket implements ServerPacket { public abstract class AbstractServerPacket implements ServerPacket {
/**
* The packet {@link Logger} instance
*/
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
/** /**
* The packet OPCODE * The packet OPCODE
*/ */

View File

@@ -16,12 +16,17 @@
*/ */
package com.l2jserver.game.net.packet.client; package com.l2jserver.game.net.packet.client;
import static com.l2jserver.game.net.packet.server.SM_CHAR_CREATE_FAIL.Reason.REASON_16_ENG_CHARS;
import static com.l2jserver.game.net.packet.server.SM_CHAR_CREATE_FAIL.Reason.REASON_CHOOSE_ANOTHER_SVR;
import static com.l2jserver.game.net.packet.server.SM_CHAR_CREATE_FAIL.Reason.REASON_CREATION_FAILED;
import static com.l2jserver.game.net.packet.server.SM_CHAR_CREATE_FAIL.Reason.REASON_NAME_ALREADY_EXISTS;
import static com.l2jserver.game.net.packet.server.SM_CHAR_CREATE_FAIL.Reason.REASON_TOO_MANY_CHARACTERS;
import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffer;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.l2jserver.game.net.Lineage2Client; import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractClientPacket; import com.l2jserver.game.net.packet.AbstractClientPacket;
import com.l2jserver.game.net.packet.server.SM_CHAR_CREATE_FAIL;
import com.l2jserver.game.net.packet.server.SM_CHAR_CREATE_OK; import com.l2jserver.game.net.packet.server.SM_CHAR_CREATE_OK;
import com.l2jserver.model.template.actor.ActorSex; import com.l2jserver.model.template.actor.ActorSex;
import com.l2jserver.model.template.character.CharacterClass; import com.l2jserver.model.template.character.CharacterClass;
@@ -30,10 +35,14 @@ import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.character.CharacterAppearance.CharacterFace; import com.l2jserver.model.world.character.CharacterAppearance.CharacterFace;
import com.l2jserver.model.world.character.CharacterAppearance.CharacterHairColor; import com.l2jserver.model.world.character.CharacterAppearance.CharacterHairColor;
import com.l2jserver.model.world.character.CharacterAppearance.CharacterHairStyle; import com.l2jserver.model.world.character.CharacterAppearance.CharacterHairStyle;
import com.l2jserver.service.game.character.CharacteCreationNotAllowedException;
import com.l2jserver.service.game.character.CharacterInvalidAppearanceException; import com.l2jserver.service.game.character.CharacterInvalidAppearanceException;
import com.l2jserver.service.game.character.CharacterInvalidNameException; import com.l2jserver.service.game.character.CharacterInvalidNameException;
import com.l2jserver.service.game.character.CharacterInvalidRaceException;
import com.l2jserver.service.game.character.CharacterInvalidSexException;
import com.l2jserver.service.game.character.CharacterNameAlreadyExistsException; import com.l2jserver.service.game.character.CharacterNameAlreadyExistsException;
import com.l2jserver.service.game.character.CharacterService; import com.l2jserver.service.game.character.CharacterService;
import com.l2jserver.service.game.character.TooManyCharactersException;
import com.l2jserver.util.BufferUtils; import com.l2jserver.util.BufferUtils;
/** /**
@@ -126,7 +135,8 @@ public class CM_CHAR_CREATE extends AbstractClientPacket {
private CharacterFace face; private CharacterFace face;
/** /**
* @param characterService the character service * @param characterService
* the character service
*/ */
@Inject @Inject
public CM_CHAR_CREATE(CharacterService characterService) { public CM_CHAR_CREATE(CharacterService characterService) {
@@ -162,17 +172,19 @@ public class CM_CHAR_CREATE extends AbstractClientPacket {
if (character != null) if (character != null)
conn.write(SM_CHAR_CREATE_OK.INSTANCE); conn.write(SM_CHAR_CREATE_OK.INSTANCE);
else else
conn.write(new SM_CHAR_CREATE_FAIL( conn.write(REASON_CREATION_FAILED.newInstance());
SM_CHAR_CREATE_FAIL.Reason.REASON_CREATION_FAILED));
} catch (CharacterInvalidNameException e) { } catch (CharacterInvalidNameException e) {
conn.write(new SM_CHAR_CREATE_FAIL( conn.write(REASON_16_ENG_CHARS.newInstance());
SM_CHAR_CREATE_FAIL.Reason.REASON_16_ENG_CHARS));
} catch (CharacterInvalidAppearanceException e) { } catch (CharacterInvalidAppearanceException e) {
conn.write(new SM_CHAR_CREATE_FAIL( conn.write(REASON_CREATION_FAILED.newInstance());
SM_CHAR_CREATE_FAIL.Reason.REASON_CREATION_FAILED));
} catch (CharacterNameAlreadyExistsException e) { } catch (CharacterNameAlreadyExistsException e) {
conn.write(new SM_CHAR_CREATE_FAIL( conn.write(REASON_NAME_ALREADY_EXISTS.newInstance());
SM_CHAR_CREATE_FAIL.Reason.REASON_NAME_ALREADY_EXISTS)); } catch (CharacteCreationNotAllowedException e) {
conn.write(REASON_CREATION_FAILED.newInstance());
} catch (CharacterInvalidRaceException | CharacterInvalidSexException e) {
conn.write(REASON_CHOOSE_ANOTHER_SVR.newInstance());
} catch (TooManyCharactersException e) {
conn.write(REASON_TOO_MANY_CHARACTERS.newInstance());
} }
} }
} }

View File

@@ -84,15 +84,25 @@ public class SM_CHAR_CREATE_FAIL extends AbstractServerPacket {
public final int id; public final int id;
/** /**
* @param id the reason id * @param id
* the reason id
*/ */
Reason(int id) { Reason(int id) {
this.id = id; this.id = id;
} }
/**
* @return an {@link SM_CHAR_CREATE_FAIL} instance for this enum
* constant
*/
public SM_CHAR_CREATE_FAIL newInstance() {
return new SM_CHAR_CREATE_FAIL(this);
}
} }
/** /**
* @param reason the reason * @param reason
* the reason
*/ */
public SM_CHAR_CREATE_FAIL(Reason reason) { public SM_CHAR_CREATE_FAIL(Reason reason) {
super(OPCODE); super(OPCODE);

View File

@@ -0,0 +1,31 @@
/*
* 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.service.game.character;
/**
* Exception thrown when the character creation is disabled or not authrorized
* for the account.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CharacteCreationNotAllowedException extends
CharacterServiceException {
/**
* The Java Serialization API serial
*/
private static final long serialVersionUID = 1L;
}

View File

@@ -0,0 +1,30 @@
/*
* 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.service.game.character;
/**
* Exception thrown when the character creation does not allows the requested
* race
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CharacterInvalidRaceException extends CharacterServiceException {
/**
* The Java Serialization API serial
*/
private static final long serialVersionUID = 1L;
}

View File

@@ -0,0 +1,30 @@
/*
* 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.service.game.character;
/**
* Exception thrown when the character creation does not allows the requested
* sex
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CharacterInvalidSexException extends CharacterServiceException {
/**
* The Java Serialization API serial
*/
private static final long serialVersionUID = 1L;
}

View File

@@ -46,6 +46,16 @@ import com.l2jserver.util.geometry.Point3D;
* @author <a href="http://www.rogiel.com">Rogiel</a> * @author <a href="http://www.rogiel.com">Rogiel</a>
*/ */
public interface CharacterService extends Service { public interface CharacterService extends Service {
/**
* Checks whether the service and the given account can create new
* characters on this server.
*
* @param accountID
* the account ID
* @return <code>true</code> if new characters are permitted
*/
boolean canCreate(AccountID accountID);
/** /**
* *
* @param name * @param name
@@ -70,13 +80,27 @@ public interface CharacterService extends Service {
* if the appearance sent by the client is not valid * if the appearance sent by the client is not valid
* @throws CharacterNameAlreadyExistsException * @throws CharacterNameAlreadyExistsException
* the character name is already being used * the character name is already being used
* @throws CharacteCreationNotAllowedException
* if the character creation is disabled or not allowed for the
* account
* @throws CharacterInvalidRaceException
* if the service does not allow the creation of characters in
* the requested race
* @throws CharacterInvalidSexException
* if the service does not allow the creation of characters in
* the requested sex
* @throws TooManyCharactersException
* if the character limit has been exceeded and no more
* characters can be created on this account
*/ */
L2Character create(String name, AccountID accountID, ActorSex sex, L2Character create(String name, AccountID accountID, ActorSex sex,
CharacterClass characterClass, CharacterHairStyle hairStyle, CharacterClass characterClass, CharacterHairStyle hairStyle,
CharacterHairColor hairColor, CharacterFace face) CharacterHairColor hairColor, CharacterFace face)
throws CharacterInvalidNameException, throws CharacterInvalidNameException,
CharacterInvalidAppearanceException, CharacterInvalidAppearanceException,
CharacterNameAlreadyExistsException; CharacterNameAlreadyExistsException,
CharacteCreationNotAllowedException, CharacterInvalidRaceException,
CharacterInvalidSexException, TooManyCharactersException;
/** /**
* Perform all operations required to this character join the world * Perform all operations required to this character join the world

View File

@@ -0,0 +1,90 @@
/*
* 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.service.game.character;
import com.l2jserver.model.template.actor.ActorSex;
import com.l2jserver.model.template.character.CharacterRace;
import com.l2jserver.service.ServiceConfiguration;
import com.l2jserver.service.configuration.XMLConfigurationService.ConfigurationXPath;
/**
* Configuration interface for {@link CharacterService}
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface CharacterServiceConfiguration extends ServiceConfiguration {
/**
* @return whether the creation of new characters is available
*/
@ConfigurationPropertyGetter(defaultValue = "true")
@ConfigurationXPath("creation/@allow")
boolean isCharacterCreationAllowed();
/**
* @param state
* whether the creation of new characters is available
*
*/
@ConfigurationPropertySetter
@ConfigurationXPath("creation/@allow")
void setCharacterCreationAllowed(boolean state);
/**
* @return the allowed races for new characters
*/
@ConfigurationPropertyGetter(defaultValue = "HUMAN|ELF|DARK_ELF|ORC|DWARF|KAMAEL")
@ConfigurationXPath("creation/@allowed-races")
CharacterRace[] getAllowedNewCharacterRaces();
/**
* @param allowedRaces
* the allowed races for new characters
*/
@ConfigurationPropertySetter
@ConfigurationXPath("creation/@allowed-races")
void setAllowedNewCharacterRaces(CharacterRace[] allowedRaces);
/**
* @return the allowed gender for new characters
*/
@ConfigurationPropertyGetter(defaultValue = "MALE|FEMALE")
@ConfigurationXPath("creation/@allowed-genders")
ActorSex[] getAllowedNewCharacterGenders();
/**
* @param allowedGenders
* the allowed genders
*/
@ConfigurationPropertySetter
@ConfigurationXPath("creation/@allowed-genders")
void setAllowedNewCharacterGenders(ActorSex[] allowedGenders);
/**
* @return the maximum number of character per account on this server
*/
@ConfigurationPropertyGetter(defaultValue = "8")
@ConfigurationXPath("creation/limits/@max-per-account")
int getMaxCharactersPerAccount();
/**
* @param maxCharactersPerAccount
* the maximum number of character per account on this server
*/
@ConfigurationPropertySetter
@ConfigurationXPath("creation/limits/@max-per-account")
void setMaxCharactersPerAccount(int maxCharactersPerAccount);
}

View File

@@ -50,7 +50,7 @@ import com.l2jserver.model.world.character.event.CharacterStartMovingEvent;
import com.l2jserver.model.world.character.event.CharacterTargetDeselectedEvent; import com.l2jserver.model.world.character.event.CharacterTargetDeselectedEvent;
import com.l2jserver.model.world.character.event.CharacterTargetSelectedEvent; import com.l2jserver.model.world.character.event.CharacterTargetSelectedEvent;
import com.l2jserver.model.world.character.event.CharacterWalkingEvent; import com.l2jserver.model.world.character.event.CharacterWalkingEvent;
import com.l2jserver.service.AbstractService; import com.l2jserver.service.AbstractConfigurableService;
import com.l2jserver.service.AbstractService.Depends; import com.l2jserver.service.AbstractService.Depends;
import com.l2jserver.service.game.AttackService; import com.l2jserver.service.game.AttackService;
import com.l2jserver.service.game.npc.NPCService; import com.l2jserver.service.game.npc.NPCService;
@@ -63,6 +63,7 @@ import com.l2jserver.service.game.world.WorldService;
import com.l2jserver.service.game.world.event.WorldEventDispatcher; import com.l2jserver.service.game.world.event.WorldEventDispatcher;
import com.l2jserver.service.network.broadcast.BroadcastService; import com.l2jserver.service.network.broadcast.BroadcastService;
import com.l2jserver.service.network.gameguard.GameGuardService; import com.l2jserver.service.network.gameguard.GameGuardService;
import com.l2jserver.util.ArrayUtils;
import com.l2jserver.util.factory.CollectionFactory; import com.l2jserver.util.factory.CollectionFactory;
import com.l2jserver.util.geometry.Coordinate; import com.l2jserver.util.geometry.Coordinate;
import com.l2jserver.util.geometry.Point3D; import com.l2jserver.util.geometry.Point3D;
@@ -73,7 +74,8 @@ import com.l2jserver.util.geometry.Point3D;
* @author <a href="http://www.rogiel.com">Rogiel</a> * @author <a href="http://www.rogiel.com">Rogiel</a>
*/ */
@Depends({ WorldService.class, SpawnService.class, AttackService.class }) @Depends({ WorldService.class, SpawnService.class, AttackService.class })
public class CharacterServiceImpl extends AbstractService implements public class CharacterServiceImpl extends
AbstractConfigurableService<CharacterServiceConfiguration> implements
CharacterService { CharacterService {
/** /**
* The logger * The logger
@@ -165,6 +167,7 @@ public class CharacterServiceImpl extends AbstractService implements
CharacterShortcutDAO shortcutDao, CharacterShortcutDAO shortcutDao,
CharacterTemplateIDProvider charTemplateIdProvider, CharacterTemplateIDProvider charTemplateIdProvider,
CharacterIDProvider charIdProvider) { CharacterIDProvider charIdProvider) {
super(CharacterServiceConfiguration.class);
this.broadcastService = broadcastService; this.broadcastService = broadcastService;
this.eventDispatcher = eventDispatcher; this.eventDispatcher = eventDispatcher;
this.spawnService = spawnService; this.spawnService = spawnService;
@@ -177,13 +180,29 @@ public class CharacterServiceImpl extends AbstractService implements
this.charIdProvider = charIdProvider; this.charIdProvider = charIdProvider;
} }
@Override
public boolean canCreate(AccountID accountID) {
if (!config.isCharacterCreationAllowed())
return false;
return characterDao.selectByAccount(accountID).size() < config
.getMaxCharactersPerAccount();
}
@Override @Override
public L2Character create(String name, AccountID accountID, ActorSex sex, public L2Character create(String name, AccountID accountID, ActorSex sex,
CharacterClass characterClass, CharacterHairStyle hairStyle, CharacterClass characterClass, CharacterHairStyle hairStyle,
CharacterHairColor hairColor, CharacterFace face) CharacterHairColor hairColor, CharacterFace face)
throws CharacterInvalidNameException, throws CharacterInvalidNameException,
CharacterInvalidAppearanceException, CharacterInvalidAppearanceException,
CharacterNameAlreadyExistsException { CharacterNameAlreadyExistsException,
CharacteCreationNotAllowedException, CharacterInvalidRaceException,
CharacterInvalidSexException, TooManyCharactersException {
if (!config.isCharacterCreationAllowed())
throw new CharacteCreationNotAllowedException();
if(characterDao.selectByAccount(accountID).size() < config
.getMaxCharactersPerAccount())
throw new TooManyCharactersException();
log.debug( log.debug(
"Requested creation of new character (name={}, sex={}, class={}, hairStyle={}, hairColor={}, face={})", "Requested creation of new character (name={}, sex={}, class={}, hairStyle={}, hairColor={}, face={})",
new Object[] { name, sex, characterClass, hairStyle, hairColor, new Object[] { name, sex, characterClass, hairStyle, hairColor,
@@ -209,6 +228,13 @@ public class CharacterServiceImpl extends AbstractService implements
final CharacterTemplateID templateId = charTemplateIdProvider final CharacterTemplateID templateId = charTemplateIdProvider
.resolveID(characterClass.id); .resolveID(characterClass.id);
final CharacterTemplate template = templateId.getTemplate(); final CharacterTemplate template = templateId.getTemplate();
if (!ArrayUtils.contains(config.getAllowedNewCharacterRaces(),
template.getRace()))
throw new CharacterInvalidRaceException();
if (!ArrayUtils.contains(config.getAllowedNewCharacterGenders(), sex))
throw new CharacterInvalidSexException();
log.debug("Creating character with template {}", template); log.debug("Creating character with template {}", template);
// everything is fine, allocate a new ID // everything is fine, allocate a new ID

View File

@@ -0,0 +1,31 @@
/*
* 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.service.game.character;
/**
* Exception thrown when the character is trying to create a new character when
* the creation limit has been exceeded.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class TooManyCharactersException extends
CharacterServiceException {
/**
* The Java Serialization API serial
*/
private static final long serialVersionUID = 1L;
}