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);
}
}
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.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;
}
}

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

@@ -47,7 +47,7 @@
you normally don't need to change anything here nor in the firewall. -->
<server listen="0.0.0.0:7777" />
</service>
<!-- Logging service -->
<service interface="com.l2jserver.service.core.LoggingService"
implementation="com.l2jserver.service.core.Log4JLoggingService">
@@ -88,7 +88,14 @@
<service interface="com.l2jserver.service.game.spawn.SpawnService"
implementation="com.l2jserver.service.game.spawn.SpawnServiceImpl" />
<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"
implementation="com.l2jserver.service.game.character.ShortcutServiceImpl" />
<service interface="com.l2jserver.service.game.AttackService"
@@ -99,7 +106,8 @@
implementation="com.l2jserver.service.game.item.ItemServiceImpl">
<!-- Whether drops are persisted in the database. Valid modes are: -->
<!-- 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 -->
<drop persistent="ALL" />
</service>

View File

@@ -109,7 +109,14 @@
<service interface="com.l2jserver.service.game.spawn.SpawnService"
implementation="com.l2jserver.service.game.spawn.SpawnServiceImpl" />
<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"
implementation="com.l2jserver.service.game.character.ShortcutServiceImpl" />
<service interface="com.l2jserver.service.game.AttackService"

View File

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

View File

@@ -16,12 +16,17 @@
*/
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 com.google.inject.Inject;
import com.l2jserver.game.net.Lineage2Client;
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.model.template.actor.ActorSex;
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.CharacterHairColor;
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.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.CharacterService;
import com.l2jserver.service.game.character.TooManyCharactersException;
import com.l2jserver.util.BufferUtils;
/**
@@ -126,7 +135,8 @@ public class CM_CHAR_CREATE extends AbstractClientPacket {
private CharacterFace face;
/**
* @param characterService the character service
* @param characterService
* the character service
*/
@Inject
public CM_CHAR_CREATE(CharacterService characterService) {
@@ -162,17 +172,19 @@ public class CM_CHAR_CREATE extends AbstractClientPacket {
if (character != null)
conn.write(SM_CHAR_CREATE_OK.INSTANCE);
else
conn.write(new SM_CHAR_CREATE_FAIL(
SM_CHAR_CREATE_FAIL.Reason.REASON_CREATION_FAILED));
conn.write(REASON_CREATION_FAILED.newInstance());
} catch (CharacterInvalidNameException e) {
conn.write(new SM_CHAR_CREATE_FAIL(
SM_CHAR_CREATE_FAIL.Reason.REASON_16_ENG_CHARS));
conn.write(REASON_16_ENG_CHARS.newInstance());
} catch (CharacterInvalidAppearanceException e) {
conn.write(new SM_CHAR_CREATE_FAIL(
SM_CHAR_CREATE_FAIL.Reason.REASON_CREATION_FAILED));
conn.write(REASON_CREATION_FAILED.newInstance());
} catch (CharacterNameAlreadyExistsException e) {
conn.write(new SM_CHAR_CREATE_FAIL(
SM_CHAR_CREATE_FAIL.Reason.REASON_NAME_ALREADY_EXISTS));
conn.write(REASON_NAME_ALREADY_EXISTS.newInstance());
} 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;
/**
* @param id the reason id
* @param id
* the reason id
*/
Reason(int 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) {
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>
*/
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
@@ -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

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.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
@Depends({ WorldService.class, SpawnService.class, AttackService.class })
public class CharacterServiceImpl extends AbstractService implements
public class CharacterServiceImpl extends
AbstractConfigurableService<CharacterServiceConfiguration> 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

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;
}