From 5ca0dae60105d8a30b56719c8d0952fdd13473dc Mon Sep 17 00:00:00 2001 From: Rogiel Date: Sun, 7 Aug 2011 22:57:17 -0300 Subject: [PATCH] Character creation code moved to CharacterService --- .../net/packet/client/CM_CHAR_CREATE.java | 319 ++---------------- .../CharacterInvalidAppearanceException.java | 27 ++ .../CharacterInvalidNameException.java | 27 ++ .../CharacterNameAlreadyExistsException.java | 27 ++ .../game/character/CharacterService.java | 35 ++ .../game/character/CharacterServiceImpl.java | 85 ++++- 6 files changed, 231 insertions(+), 289 deletions(-) create mode 100644 src/main/java/com/l2jserver/service/game/character/CharacterInvalidAppearanceException.java create mode 100644 src/main/java/com/l2jserver/service/game/character/CharacterInvalidNameException.java create mode 100644 src/main/java/com/l2jserver/service/game/character/CharacterNameAlreadyExistsException.java diff --git a/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_CREATE.java b/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_CREATE.java index d81e7cee6..358c43162 100644 --- a/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_CREATE.java +++ b/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_CREATE.java @@ -17,20 +17,12 @@ package com.l2jserver.game.net.packet.client; import org.jboss.netty.buffer.ChannelBuffer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; 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.dao.CharacterDAO; -import com.l2jserver.model.id.object.CharacterID; -import com.l2jserver.model.id.object.provider.CharacterIDProvider; -import com.l2jserver.model.id.template.CharacterTemplateID; -import com.l2jserver.model.id.template.provider.CharacterTemplateIDProvider; -import com.l2jserver.model.template.CharacterTemplate; import com.l2jserver.model.template.actor.ActorSex; import com.l2jserver.model.template.character.CharacterClass; import com.l2jserver.model.template.character.CharacterRace; @@ -38,6 +30,10 @@ 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.CharacterInvalidAppearanceException; +import com.l2jserver.service.game.character.CharacterInvalidNameException; +import com.l2jserver.service.game.character.CharacterNameAlreadyExistsException; +import com.l2jserver.service.game.character.CharacterService; import com.l2jserver.util.BufferUtils; /** @@ -52,25 +48,11 @@ public class CM_CHAR_CREATE extends AbstractClientPacket { */ public static final int OPCODE = 0x0c; - /** - * The logger - */ - private static final Logger log = LoggerFactory - .getLogger(CM_CHAR_CREATE.class); - // services and daos /** - * The {@link CharacterDAO} implementation + * The {@link CharacterService} implementation */ - private final CharacterDAO characterDao; - /** - * The {@link CharacterID} factory - */ - private final CharacterIDProvider characterIdFactory; - /** - * The {@link CharacterTemplateID} factory - */ - private final CharacterTemplateIDProvider characterTemplateIdProvider; + private final CharacterService characterService; // packet /** @@ -78,11 +60,14 @@ public class CM_CHAR_CREATE extends AbstractClientPacket { */ private String name; /** - * The race of the new character + * The race of the new character. Note that this is ignored and the template + * value is used. */ + @SuppressWarnings("unused") private CharacterRace race; /** - * The sex of the new character + * The sex of the new character. Note that this is ignored and the template + * value is used. */ private ActorSex sex; /** @@ -94,31 +79,37 @@ public class CM_CHAR_CREATE extends AbstractClientPacket { * The new character intelligence. Note that this is ignored and the * template value is used. */ + @SuppressWarnings("unused") private int intelligence; /** * The new character intelligence. Note that this is ignored and the * template value is used. */ + @SuppressWarnings("unused") private int strength; /** * The new character strength. Note that this is ignored and the template * value is used. */ + @SuppressWarnings("unused") private int concentration; /** * The new character concentration. Note that this is ignored and the * template value is used. */ + @SuppressWarnings("unused") private int mentality; /** * The new character mentality. Note that this is ignored and the template * value is used. */ + @SuppressWarnings("unused") private int dexterity; /** * The new character dexterity. Note that this is ignored and the template * value is used. */ + @SuppressWarnings("unused") private int witness; /** @@ -135,12 +126,8 @@ public class CM_CHAR_CREATE extends AbstractClientPacket { private CharacterFace face; @Inject - public CM_CHAR_CREATE(CharacterDAO characterDao, - CharacterIDProvider characterIdFactory, - CharacterTemplateIDProvider characterTemplateIdFactory) { - this.characterDao = characterDao; - this.characterIdFactory = characterIdFactory; - this.characterTemplateIdProvider = characterTemplateIdFactory; + public CM_CHAR_CREATE(CharacterService characterService) { + this.characterService = characterService; } @Override @@ -164,268 +151,24 @@ public class CM_CHAR_CREATE extends AbstractClientPacket { @Override public void process(final Lineage2Client conn) { - log.debug("Creating a new character, race={}, sex={}, class={}", - new Object[] { race, sex, characterClass }); - if ((name.length() < 1) || (name.length() > 16)) { - log.debug("Character name length invalid: {}. Aborting.", name); + try { + final L2Character character = characterService.create(name, sex, + characterClass, hairStyle, hairColor, face); + + 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)); + } catch (CharacterInvalidNameException e) { conn.write(new SM_CHAR_CREATE_FAIL( SM_CHAR_CREATE_FAIL.Reason.REASON_16_ENG_CHARS)); - return; - } - // TODO check alphanumeric name - if (sex == null || hairStyle == null || hairColor == null - || face == null) { - log.debug("Character appearance invalid. Aborting."); - // if some of those attributes is null, something wrong happened. - // Maybe we don't support the value sent! + } catch (CharacterInvalidAppearanceException e) { conn.write(new SM_CHAR_CREATE_FAIL( SM_CHAR_CREATE_FAIL.Reason.REASON_CREATION_FAILED)); - return; - } - // existence check - final L2Character existenceCheck = characterDao.selectByName(name); - if (existenceCheck != null) { - log.debug("Character name already exists: {}. Aborting.", name); + } catch (CharacterNameAlreadyExistsException e) { conn.write(new SM_CHAR_CREATE_FAIL( SM_CHAR_CREATE_FAIL.Reason.REASON_NAME_ALREADY_EXISTS)); - return; } - - // create template id and lookup for the template instance - final CharacterTemplateID templateId = characterTemplateIdProvider - .resolveID(characterClass.id); - final CharacterTemplate template = templateId.getTemplate(); - log.debug("Creating character with template {}", template); - - // ensure parameters passed by the client are true - if ((race != template.getRace())) { - log.debug("race, expected {}, received {}", template.getRace(), - race); - - log.debug( - "Values sent by client and from template does not match: {}", - template); - // some of the values didn't match, canceling creation - conn.write(new SM_CHAR_CREATE_FAIL( - SM_CHAR_CREATE_FAIL.Reason.REASON_CREATION_FAILED)); - return; - } - - // everything is fine, allocate a new ID - final CharacterID id = characterIdFactory.createID(); - // create the instance from the template - final L2Character character = template.create(); - - log.debug("Character object created, ID: {}, Object: {}", id, character); - - // set parameters - character.setID(id); - character.setName(name); - - character.setSex(sex); - - character.getAppearance().setHairStyle(hairStyle); - character.getAppearance().setHairColor(hairColor); - character.getAppearance().setFace(face); - - if (characterDao.save(character)) { - log.debug("Character saved to database"); - conn.write(SM_CHAR_CREATE_OK.INSTANCE); - } - } - - /** - * @return the name - */ - public String getName() { - return name; - } - - /** - * @param name - * the name to set - */ - public void setName(String name) { - this.name = name; - } - - /** - * @return the race - */ - public CharacterRace getRace() { - return race; - } - - /** - * @param race - * the race to set - */ - public void setRace(CharacterRace race) { - this.race = race; - } - - /** - * @return the sex - */ - public ActorSex getSex() { - return sex; - } - - /** - * @param sex - * the sex to set - */ - public void setSex(ActorSex sex) { - this.sex = sex; - } - - /** - * @return the character class - */ - public CharacterClass getCharacterClass() { - return characterClass; - } - - /** - * @param characterClass - * the character class - */ - public void setClassId(CharacterClass characterClass) { - this.characterClass = characterClass; - } - - /** - * @return the intelligence - */ - public int getIntelligence() { - return intelligence; - } - - /** - * @param intelligence - * the intelligence to set - */ - public void setIntelligence(int intelligence) { - this.intelligence = intelligence; - } - - /** - * @return the strength - */ - public int getStrength() { - return strength; - } - - /** - * @param strength - * the strength to set - */ - public void setStrength(int strength) { - this.strength = strength; - } - - /** - * @return the concentration - */ - public int getConcentration() { - return concentration; - } - - /** - * @param concentration - * the concentration to set - */ - public void setConcentration(int concentration) { - this.concentration = concentration; - } - - /** - * @return the mentality - */ - public int getMentality() { - return mentality; - } - - /** - * @param mentality - * the mentality to set - */ - public void setMentality(int mentality) { - this.mentality = mentality; - } - - /** - * @return the dexterity - */ - public int getDexterity() { - return dexterity; - } - - /** - * @param dexterity - * the dexterity to set - */ - public void setDexterity(int dexterity) { - this.dexterity = dexterity; - } - - /** - * @return the witness - */ - public int getWitness() { - return witness; - } - - /** - * @param witness - * the witness to set - */ - public void setWitness(int witness) { - this.witness = witness; - } - - /** - * @return the hairStyle - */ - public CharacterHairStyle getHairStyle() { - return hairStyle; - } - - /** - * @param hairStyle - * the hairStyle to set - */ - public void setHairStyle(CharacterHairStyle hairStyle) { - this.hairStyle = hairStyle; - } - - /** - * @return the hairColor - */ - public CharacterHairColor getHairColor() { - return hairColor; - } - - /** - * @param hairColor - * the hairColor to set - */ - public void setHairColor(CharacterHairColor hairColor) { - this.hairColor = hairColor; - } - - /** - * @return the face - */ - public CharacterFace getFace() { - return face; - } - - /** - * @param face - * the face to set - */ - public void setFace(CharacterFace face) { - this.face = face; } } diff --git a/src/main/java/com/l2jserver/service/game/character/CharacterInvalidAppearanceException.java b/src/main/java/com/l2jserver/service/game/character/CharacterInvalidAppearanceException.java new file mode 100644 index 000000000..36016de31 --- /dev/null +++ b/src/main/java/com/l2jserver/service/game/character/CharacterInvalidAppearanceException.java @@ -0,0 +1,27 @@ +/* + * This file is part of l2jserver . + * + * l2jserver is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * l2jserver is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with l2jserver. If not, see . + */ +package com.l2jserver.service.game.character; + +/** + * Exception thrown when the character is not in jail + * + * @author Rogiel + */ +public class CharacterInvalidAppearanceException extends + CharacterServiceException { + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/src/main/java/com/l2jserver/service/game/character/CharacterInvalidNameException.java b/src/main/java/com/l2jserver/service/game/character/CharacterInvalidNameException.java new file mode 100644 index 000000000..8410f5a4d --- /dev/null +++ b/src/main/java/com/l2jserver/service/game/character/CharacterInvalidNameException.java @@ -0,0 +1,27 @@ +/* + * This file is part of l2jserver . + * + * l2jserver is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * l2jserver is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with l2jserver. If not, see . + */ +package com.l2jserver.service.game.character; + +/** + * Exception thrown when the character is not in jail + * + * @author Rogiel + */ +public class CharacterInvalidNameException extends + CharacterServiceException { + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/src/main/java/com/l2jserver/service/game/character/CharacterNameAlreadyExistsException.java b/src/main/java/com/l2jserver/service/game/character/CharacterNameAlreadyExistsException.java new file mode 100644 index 000000000..7212ea779 --- /dev/null +++ b/src/main/java/com/l2jserver/service/game/character/CharacterNameAlreadyExistsException.java @@ -0,0 +1,27 @@ +/* + * This file is part of l2jserver . + * + * l2jserver is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * l2jserver is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with l2jserver. If not, see . + */ +package com.l2jserver.service.game.character; + +/** + * Exception thrown when the character is not in jail + * + * @author Rogiel + */ +public class CharacterNameAlreadyExistsException extends + CharacterServiceException { + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/src/main/java/com/l2jserver/service/game/character/CharacterService.java b/src/main/java/com/l2jserver/service/game/character/CharacterService.java index 677e5f743..c491464e9 100644 --- a/src/main/java/com/l2jserver/service/game/character/CharacterService.java +++ b/src/main/java/com/l2jserver/service/game/character/CharacterService.java @@ -17,9 +17,14 @@ package com.l2jserver.service.game.character; import com.l2jserver.model.game.CharacterFriend; +import com.l2jserver.model.template.actor.ActorSex; +import com.l2jserver.model.template.character.CharacterClass; import com.l2jserver.model.world.Actor; import com.l2jserver.model.world.Item; 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.Service; import com.l2jserver.service.game.npc.NotAttackableNPCServiceException; import com.l2jserver.service.game.spawn.AlreadySpawnedServiceException; @@ -40,6 +45,36 @@ import com.l2jserver.util.geometry.Point3D; * @author Rogiel */ public interface CharacterService extends Service { + /** + * + * @param name + * The name of the new character + * @param sex + * The sex of the new character + * @param characterClass + * The class of the new character + * @param hairStyle + * The new character hair style + * @param hairColor + * The new character hair color + * @param face + * The new character face + * @return the newly created {@link L2Character} object + * @throws CharacterInvalidNameException + * if the character name contains invalid characters, too long + * or not long enough + * @throws CharacterInvalidAppearanceException + * if the appearance sent by the client is not valid + * @throws CharacterNameAlreadyExistsException + * the character name is already being used + */ + L2Character create(String name, ActorSex sex, + CharacterClass characterClass, CharacterHairStyle hairStyle, + CharacterHairColor hairColor, CharacterFace face) + throws CharacterInvalidNameException, + CharacterInvalidAppearanceException, + CharacterNameAlreadyExistsException; + /** * Perform all operations required to this character join the world * diff --git a/src/main/java/com/l2jserver/service/game/character/CharacterServiceImpl.java b/src/main/java/com/l2jserver/service/game/character/CharacterServiceImpl.java index 0d2358dba..53f76213d 100644 --- a/src/main/java/com/l2jserver/service/game/character/CharacterServiceImpl.java +++ b/src/main/java/com/l2jserver/service/game/character/CharacterServiceImpl.java @@ -16,6 +16,9 @@ */ package com.l2jserver.service.game.character; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.google.common.base.Preconditions; import com.google.inject.Inject; import com.l2jserver.game.net.Lineage2Client; @@ -28,14 +31,24 @@ import com.l2jserver.game.net.packet.server.SM_ITEM_GROUND; import com.l2jserver.game.net.packet.server.SM_MOVE; import com.l2jserver.game.net.packet.server.SM_MOVE_TYPE; import com.l2jserver.game.net.packet.server.SM_TARGET; +import com.l2jserver.model.dao.CharacterDAO; import com.l2jserver.model.dao.ItemDAO; import com.l2jserver.model.id.object.CharacterID; +import com.l2jserver.model.id.object.provider.CharacterIDProvider; +import com.l2jserver.model.id.template.CharacterTemplateID; +import com.l2jserver.model.id.template.provider.CharacterTemplateIDProvider; import com.l2jserver.model.server.ChatMessage; +import com.l2jserver.model.template.CharacterTemplate; +import com.l2jserver.model.template.actor.ActorSex; +import com.l2jserver.model.template.character.CharacterClass; import com.l2jserver.model.world.Actor; import com.l2jserver.model.world.Actor.ActorState; import com.l2jserver.model.world.L2Character; import com.l2jserver.model.world.L2Character.CharacterMoveType; import com.l2jserver.model.world.NPC; +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.model.world.character.event.CharacterEnterWorldEvent; import com.l2jserver.model.world.character.event.CharacterEvent; import com.l2jserver.model.world.character.event.CharacterLeaveWorldEvent; @@ -76,6 +89,12 @@ import com.l2jserver.util.geometry.Point3D; BroadcastService.class }) public class CharacterServiceImpl extends AbstractService implements CharacterService { + /** + * The logger + */ + private static final Logger log = LoggerFactory + .getLogger(CharacterServiceImpl.class); + /** * The {@link BroadcastService} */ @@ -104,11 +123,19 @@ public class CharacterServiceImpl extends AbstractService implements * The {@link GameGuardService} */ private final GameGuardService ggService; + + /** + * The {@link CharacterDAO} + */ + private final CharacterDAO characterDao; /** * The {@link ItemDAO} */ private final ItemDAO itemDao; + private final CharacterIDProvider charIdProvider; + private final CharacterTemplateIDProvider charTemplateIdProvider; + // /** // * The {@link AIService} // */ @@ -118,7 +145,10 @@ public class CharacterServiceImpl extends AbstractService implements public CharacterServiceImpl(BroadcastService broadcastService, WorldEventDispatcher eventDispatcher, ChatService chatService, NetworkService networkService, SpawnService spawnService, - NPCService npcService, GameGuardService ggService, ItemDAO itemDao) { + NPCService npcService, GameGuardService ggService, + CharacterDAO characterDao, ItemDAO itemDao, + CharacterTemplateIDProvider charTemplateIdProvider, + CharacterIDProvider charIdProvider) { this.broadcastService = broadcastService; this.eventDispatcher = eventDispatcher; this.chatService = chatService; @@ -126,7 +156,60 @@ public class CharacterServiceImpl extends AbstractService implements this.spawnService = spawnService; this.npcService = npcService; this.ggService = ggService; + this.characterDao = characterDao; this.itemDao = itemDao; + this.charTemplateIdProvider = charTemplateIdProvider; + this.charIdProvider = charIdProvider; + } + + @Override + public L2Character create(String name, ActorSex sex, + CharacterClass characterClass, CharacterHairStyle hairStyle, + CharacterHairColor hairColor, CharacterFace face) + throws CharacterInvalidNameException, + CharacterInvalidAppearanceException, + CharacterNameAlreadyExistsException { + if ((name.length() < 1) || (name.length() > 16)) { + throw new CharacterInvalidNameException(); + } + // TODO check alphanumeric name + if (sex == null || hairStyle == null || hairColor == null + || face == null) + // if some of those attributes is null, something wrong happened. + // Maybe we don't support the value sent! + throw new CharacterInvalidAppearanceException(); + + // existence check + final L2Character existenceCheck = characterDao.selectByName(name); + if (existenceCheck != null) + throw new CharacterNameAlreadyExistsException(); + + // create template id and lookup for the template instance + final CharacterTemplateID templateId = charTemplateIdProvider + .resolveID(characterClass.id); + final CharacterTemplate template = templateId.getTemplate(); + log.debug("Creating character with template {}", template); + + // everything is fine, allocate a new ID + final CharacterID id = charIdProvider.createID(); + // create the instance from the template + final L2Character character = template.create(); + + log.debug("Character object created, ID: {}, Object: {}", id, character); + + // set parameters + character.setID(id); + character.setName(name); + + character.setSex(sex); + + character.getAppearance().setHairStyle(hairStyle); + character.getAppearance().setHairColor(hairColor); + character.getAppearance().setFace(face); + + if (characterDao.save(character)) + return character; + return null; } @Override