diff --git a/l2jserver2-common/src/main/java/com/l2jserver/util/ArrayUtils.java b/l2jserver2-common/src/main/java/com/l2jserver/util/ArrayUtils.java index d6ac46d0e..66b2c4283 100644 --- a/l2jserver2-common/src/main/java/com/l2jserver/util/ArrayUtils.java +++ b/l2jserver2-common/src/main/java/com/l2jserver/util/ArrayUtils.java @@ -50,6 +50,22 @@ public class ArrayUtils { 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 expected item to be in the + * array. + * + * @param array + * the array to search in + * @param expected + * the item to be looked in the array + * @return true if the item exists, false + * otherwise + */ + public final static boolean contains(T[] array, T expected) { + return Arrays.binarySearch(array, expected) >= 0; } } diff --git a/l2jserver2-common/src/main/java/com/l2jserver/util/transformer/TransformerFactory.java b/l2jserver2-common/src/main/java/com/l2jserver/util/transformer/TransformerFactory.java index 6935c7dae..3230c7a73 100644 --- a/l2jserver2-common/src/main/java/com/l2jserver/util/transformer/TransformerFactory.java +++ b/l2jserver2-common/src/main/java/com/l2jserver/util/transformer/TransformerFactory.java @@ -22,6 +22,7 @@ import java.net.URI; import java.net.URL; 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.ByteTransformer; 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.PathTransformer; 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.URLTransformer; @@ -78,9 +80,12 @@ public class TransformerFactory { return URLTransformer.SHARED_INSTANCE; } else if (type == Path.class) { return PathTransformer.SHARED_INSTANCE; - } else if(type.isEnum()) { + } else if (type.isEnum()) { return EnumTransformer.SHARED_INSTANCE; - } + } else if(type.isArray()) { + return ArrayTransformer.SHARED_INSTANCE; + } else if (type == String.class) + return StringTransformer.SHARED_INSTANCE; return null; } } diff --git a/l2jserver2-common/src/main/java/com/l2jserver/util/transformer/impl/ArrayTransformer.java b/l2jserver2-common/src/main/java/com/l2jserver/util/transformer/impl/ArrayTransformer.java new file mode 100644 index 000000000..3b289a0b0 --- /dev/null +++ b/l2jserver2-common/src/main/java/com/l2jserver/util/transformer/impl/ArrayTransformer.java @@ -0,0 +1,72 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +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. + *

+ * Important note: Array elements are by an |. + * + * @author Rogiel + * @param + * the array component type that this tranformer transforms + */ +public class ArrayTransformer implements Transformer { + /** + * This transformer shared instance + */ + @SuppressWarnings("rawtypes") + public static final ArrayTransformer SHARED_INSTANCE = new ArrayTransformer(); + + @Override + @SuppressWarnings("unchecked") + public String transform(Class type, T[] value) { + final Transformer transformer = (Transformer) TransformerFactory + .getTransfromer(type.getComponentType()); + final String[] values = new String[value.length]; + int i = 0; + for (final T item : value) { + values[i++] = transformer.transform( + (Class) type.getComponentType(), item); + } + return StringUtils.join(values, '|'); + } + + @Override + @SuppressWarnings("unchecked") + public T[] untransform(Class type, String stringValue) { + final Transformer transformer = (Transformer) 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) type.getComponentType(), value); + } + + return values; + } +} diff --git a/l2jserver2-common/src/main/java/com/l2jserver/util/transformer/impl/StringTransformer.java b/l2jserver2-common/src/main/java/com/l2jserver/util/transformer/impl/StringTransformer.java new file mode 100644 index 000000000..f411dbef6 --- /dev/null +++ b/l2jserver2-common/src/main/java/com/l2jserver/util/transformer/impl/StringTransformer.java @@ -0,0 +1,42 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.util.transformer.impl; + +import com.l2jserver.util.transformer.Transformer; + +/** + * This tranformer does nothing! + * + * @author Rogiel + */ +public class StringTransformer implements Transformer { + /** + * This transformer shared instance + */ + public static final StringTransformer SHARED_INSTANCE = new StringTransformer(); + + @Override + public String transform(Class type, String value) { + return value; + } + + @Override + public String untransform(Class type, String value) { + return value; + } + +} diff --git a/l2jserver2-common/src/test/java/com/l2jserver/util/transformer/impl/ArrayTransformerTest.java b/l2jserver2-common/src/test/java/com/l2jserver/util/transformer/impl/ArrayTransformerTest.java new file mode 100644 index 000000000..bfd02031a --- /dev/null +++ b/l2jserver2-common/src/test/java/com/l2jserver/util/transformer/impl/ArrayTransformerTest.java @@ -0,0 +1,94 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.util.transformer.impl; + +import org.junit.Assert; +import org.junit.Test; + +/** + * @author Rogiel + * + */ +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 transformer = new ArrayTransformer(); + 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 transformer = new ArrayTransformer(); + 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> transformer = new ArrayTransformer>(); + Assert.assertEquals(CLASS_ARRAY_STRING, transformer.transform( + (Class[]>) Class[].class, CLASS_ARRAY)); + Assert.assertArrayEquals(CLASS_ARRAY, transformer + .untransform((Class[]>) Class[].class, + CLASS_ARRAY_STRING)); + } + +} diff --git a/l2jserver2-gameserver/distribution/services.xml b/l2jserver2-gameserver/distribution/services.xml index a959bff0a..bc16dd81d 100644 --- a/l2jserver2-gameserver/distribution/services.xml +++ b/l2jserver2-gameserver/distribution/services.xml @@ -47,7 +47,7 @@ you normally don't need to change anything here nor in the firewall. --> - + @@ -88,7 +88,14 @@ + implementation="com.l2jserver.service.game.character.CharacterServiceImpl"> + + + + + + - + diff --git a/l2jserver2-gameserver/services-sample.xml b/l2jserver2-gameserver/services-sample.xml index 1a271c8d8..14f95c415 100644 --- a/l2jserver2-gameserver/services-sample.xml +++ b/l2jserver2-gameserver/services-sample.xml @@ -109,7 +109,14 @@ + implementation="com.l2jserver.service.game.character.CharacterServiceImpl"> + + + + + + . + * + * 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 . + */ +package com.l2jserver.service.game.character; + +/** + * Exception thrown when the character creation is disabled or not authrorized + * for the account. + * + * @author Rogiel + */ +public class CharacteCreationNotAllowedException extends + CharacterServiceException { + /** + * The Java Serialization API serial + */ + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/character/CharacterInvalidRaceException.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/character/CharacterInvalidRaceException.java new file mode 100644 index 000000000..ca8ccda6b --- /dev/null +++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/character/CharacterInvalidRaceException.java @@ -0,0 +1,30 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.service.game.character; + +/** + * Exception thrown when the character creation does not allows the requested + * race + * + * @author Rogiel + */ +public class CharacterInvalidRaceException extends CharacterServiceException { + /** + * The Java Serialization API serial + */ + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/character/CharacterInvalidSexException.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/character/CharacterInvalidSexException.java new file mode 100644 index 000000000..09aff01ef --- /dev/null +++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/character/CharacterInvalidSexException.java @@ -0,0 +1,30 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.service.game.character; + +/** + * Exception thrown when the character creation does not allows the requested + * sex + * + * @author Rogiel + */ +public class CharacterInvalidSexException extends CharacterServiceException { + /** + * The Java Serialization API serial + */ + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/character/CharacterService.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/character/CharacterService.java index 07a3fc355..5fb723164 100644 --- a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/character/CharacterService.java +++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/character/CharacterService.java @@ -46,6 +46,16 @@ import com.l2jserver.util.geometry.Point3D; * @author Rogiel */ 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 true if new characters are permitted + */ + boolean canCreate(AccountID accountID); + /** * * @param name @@ -70,13 +80,27 @@ public interface CharacterService extends Service { * if the appearance sent by the client is not valid * @throws CharacterNameAlreadyExistsException * 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, CharacterClass characterClass, CharacterHairStyle hairStyle, CharacterHairColor hairColor, CharacterFace face) throws CharacterInvalidNameException, CharacterInvalidAppearanceException, - CharacterNameAlreadyExistsException; + CharacterNameAlreadyExistsException, + CharacteCreationNotAllowedException, CharacterInvalidRaceException, + CharacterInvalidSexException, TooManyCharactersException; /** * Perform all operations required to this character join the world diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/character/CharacterServiceConfiguration.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/character/CharacterServiceConfiguration.java new file mode 100644 index 000000000..575b6dbfe --- /dev/null +++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/character/CharacterServiceConfiguration.java @@ -0,0 +1,90 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +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 Rogiel + */ +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); +} diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/character/CharacterServiceImpl.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/character/CharacterServiceImpl.java index dc2f89a5c..e5106b8a5 100644 --- a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/character/CharacterServiceImpl.java +++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/character/CharacterServiceImpl.java @@ -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.CharacterTargetSelectedEvent; 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.game.AttackService; 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.network.broadcast.BroadcastService; import com.l2jserver.service.network.gameguard.GameGuardService; +import com.l2jserver.util.ArrayUtils; import com.l2jserver.util.factory.CollectionFactory; import com.l2jserver.util.geometry.Coordinate; import com.l2jserver.util.geometry.Point3D; @@ -73,7 +74,8 @@ import com.l2jserver.util.geometry.Point3D; * @author Rogiel */ @Depends({ WorldService.class, SpawnService.class, AttackService.class }) -public class CharacterServiceImpl extends AbstractService implements +public class CharacterServiceImpl extends + AbstractConfigurableService implements CharacterService { /** * The logger @@ -165,6 +167,7 @@ public class CharacterServiceImpl extends AbstractService implements CharacterShortcutDAO shortcutDao, CharacterTemplateIDProvider charTemplateIdProvider, CharacterIDProvider charIdProvider) { + super(CharacterServiceConfiguration.class); this.broadcastService = broadcastService; this.eventDispatcher = eventDispatcher; this.spawnService = spawnService; @@ -177,13 +180,29 @@ public class CharacterServiceImpl extends AbstractService implements this.charIdProvider = charIdProvider; } + @Override + public boolean canCreate(AccountID accountID) { + if (!config.isCharacterCreationAllowed()) + return false; + return characterDao.selectByAccount(accountID).size() < config + .getMaxCharactersPerAccount(); + } + @Override public L2Character create(String name, AccountID accountID, ActorSex sex, CharacterClass characterClass, CharacterHairStyle hairStyle, CharacterHairColor hairColor, CharacterFace face) throws CharacterInvalidNameException, 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( "Requested creation of new character (name={}, sex={}, class={}, hairStyle={}, hairColor={}, face={})", new Object[] { name, sex, characterClass, hairStyle, hairColor, @@ -209,6 +228,13 @@ public class CharacterServiceImpl extends AbstractService implements final CharacterTemplateID templateId = charTemplateIdProvider .resolveID(characterClass.id); 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); // everything is fine, allocate a new ID diff --git a/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/character/TooManyCharactersException.java b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/character/TooManyCharactersException.java new file mode 100644 index 000000000..6c4415f4c --- /dev/null +++ b/l2jserver2-gameserver/src/main/java/com/l2jserver/service/game/character/TooManyCharactersException.java @@ -0,0 +1,31 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +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 Rogiel + */ +public class TooManyCharactersException extends + CharacterServiceException { + /** + * The Java Serialization API serial + */ + private static final long serialVersionUID = 1L; +} \ No newline at end of file