1
0
mirror of https://github.com/Rogiel/l2jserver2 synced 2025-12-06 07:32:46 +00:00

Character creation code moved to CharacterService

This commit is contained in:
2011-08-07 22:57:17 -03:00
parent 4fe7eeb95b
commit 5ca0dae601
6 changed files with 231 additions and 289 deletions

View File

@@ -17,20 +17,12 @@
package com.l2jserver.game.net.packet.client; package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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_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.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.actor.ActorSex;
import com.l2jserver.model.template.character.CharacterClass; import com.l2jserver.model.template.character.CharacterClass;
import com.l2jserver.model.template.character.CharacterRace; 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.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.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; import com.l2jserver.util.BufferUtils;
/** /**
@@ -52,25 +48,11 @@ public class CM_CHAR_CREATE extends AbstractClientPacket {
*/ */
public static final int OPCODE = 0x0c; public static final int OPCODE = 0x0c;
/**
* The logger
*/
private static final Logger log = LoggerFactory
.getLogger(CM_CHAR_CREATE.class);
// services and daos // services and daos
/** /**
* The {@link CharacterDAO} implementation * The {@link CharacterService} implementation
*/ */
private final CharacterDAO characterDao; private final CharacterService characterService;
/**
* The {@link CharacterID} factory
*/
private final CharacterIDProvider characterIdFactory;
/**
* The {@link CharacterTemplateID} factory
*/
private final CharacterTemplateIDProvider characterTemplateIdProvider;
// packet // packet
/** /**
@@ -78,11 +60,14 @@ public class CM_CHAR_CREATE extends AbstractClientPacket {
*/ */
private String name; 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; 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; 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 * The new character intelligence. Note that this is ignored and the
* template value is used. * template value is used.
*/ */
@SuppressWarnings("unused")
private int intelligence; private int intelligence;
/** /**
* The new character intelligence. Note that this is ignored and the * The new character intelligence. Note that this is ignored and the
* template value is used. * template value is used.
*/ */
@SuppressWarnings("unused")
private int strength; private int strength;
/** /**
* The new character strength. Note that this is ignored and the template * The new character strength. Note that this is ignored and the template
* value is used. * value is used.
*/ */
@SuppressWarnings("unused")
private int concentration; private int concentration;
/** /**
* The new character concentration. Note that this is ignored and the * The new character concentration. Note that this is ignored and the
* template value is used. * template value is used.
*/ */
@SuppressWarnings("unused")
private int mentality; private int mentality;
/** /**
* The new character mentality. Note that this is ignored and the template * The new character mentality. Note that this is ignored and the template
* value is used. * value is used.
*/ */
@SuppressWarnings("unused")
private int dexterity; private int dexterity;
/** /**
* The new character dexterity. Note that this is ignored and the template * The new character dexterity. Note that this is ignored and the template
* value is used. * value is used.
*/ */
@SuppressWarnings("unused")
private int witness; private int witness;
/** /**
@@ -135,12 +126,8 @@ public class CM_CHAR_CREATE extends AbstractClientPacket {
private CharacterFace face; private CharacterFace face;
@Inject @Inject
public CM_CHAR_CREATE(CharacterDAO characterDao, public CM_CHAR_CREATE(CharacterService characterService) {
CharacterIDProvider characterIdFactory, this.characterService = characterService;
CharacterTemplateIDProvider characterTemplateIdFactory) {
this.characterDao = characterDao;
this.characterIdFactory = characterIdFactory;
this.characterTemplateIdProvider = characterTemplateIdFactory;
} }
@Override @Override
@@ -164,268 +151,24 @@ public class CM_CHAR_CREATE extends AbstractClientPacket {
@Override @Override
public void process(final Lineage2Client conn) { public void process(final Lineage2Client conn) {
log.debug("Creating a new character, race={}, sex={}, class={}", try {
new Object[] { race, sex, characterClass }); final L2Character character = characterService.create(name, sex,
if ((name.length() < 1) || (name.length() > 16)) { characterClass, hairStyle, hairColor, face);
log.debug("Character name length invalid: {}. Aborting.", name);
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( conn.write(new SM_CHAR_CREATE_FAIL(
SM_CHAR_CREATE_FAIL.Reason.REASON_16_ENG_CHARS)); SM_CHAR_CREATE_FAIL.Reason.REASON_16_ENG_CHARS));
return; } catch (CharacterInvalidAppearanceException e) {
}
// 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!
conn.write(new SM_CHAR_CREATE_FAIL( conn.write(new SM_CHAR_CREATE_FAIL(
SM_CHAR_CREATE_FAIL.Reason.REASON_CREATION_FAILED)); SM_CHAR_CREATE_FAIL.Reason.REASON_CREATION_FAILED));
return; } catch (CharacterNameAlreadyExistsException e) {
}
// existence check
final L2Character existenceCheck = characterDao.selectByName(name);
if (existenceCheck != null) {
log.debug("Character name already exists: {}. Aborting.", name);
conn.write(new SM_CHAR_CREATE_FAIL( conn.write(new SM_CHAR_CREATE_FAIL(
SM_CHAR_CREATE_FAIL.Reason.REASON_NAME_ALREADY_EXISTS)); 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;
} }
} }

View File

@@ -0,0 +1,27 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.game.character;
/**
* Exception thrown when the character is <b>not</b> in jail
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CharacterInvalidAppearanceException extends
CharacterServiceException {
private static final long serialVersionUID = 1L;
}

View File

@@ -0,0 +1,27 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.game.character;
/**
* Exception thrown when the character is <b>not</b> in jail
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CharacterInvalidNameException extends
CharacterServiceException {
private static final long serialVersionUID = 1L;
}

View File

@@ -0,0 +1,27 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.game.character;
/**
* Exception thrown when the character is <b>not</b> in jail
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CharacterNameAlreadyExistsException extends
CharacterServiceException {
private static final long serialVersionUID = 1L;
}

View File

@@ -17,9 +17,14 @@
package com.l2jserver.service.game.character; package com.l2jserver.service.game.character;
import com.l2jserver.model.game.CharacterFriend; 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.Actor;
import com.l2jserver.model.world.Item; import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.L2Character; 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.Service;
import com.l2jserver.service.game.npc.NotAttackableNPCServiceException; import com.l2jserver.service.game.npc.NotAttackableNPCServiceException;
import com.l2jserver.service.game.spawn.AlreadySpawnedServiceException; import com.l2jserver.service.game.spawn.AlreadySpawnedServiceException;
@@ -40,6 +45,36 @@ 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 {
/**
*
* @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 * Perform all operations required to this character join the world
* *

View File

@@ -16,6 +16,9 @@
*/ */
package com.l2jserver.service.game.character; package com.l2jserver.service.game.character;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.l2jserver.game.net.Lineage2Client; 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;
import com.l2jserver.game.net.packet.server.SM_MOVE_TYPE; import com.l2jserver.game.net.packet.server.SM_MOVE_TYPE;
import com.l2jserver.game.net.packet.server.SM_TARGET; 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.dao.ItemDAO;
import com.l2jserver.model.id.object.CharacterID; 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.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;
import com.l2jserver.model.world.Actor.ActorState; import com.l2jserver.model.world.Actor.ActorState;
import com.l2jserver.model.world.L2Character; import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.L2Character.CharacterMoveType; import com.l2jserver.model.world.L2Character.CharacterMoveType;
import com.l2jserver.model.world.NPC; 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.CharacterEnterWorldEvent;
import com.l2jserver.model.world.character.event.CharacterEvent; import com.l2jserver.model.world.character.event.CharacterEvent;
import com.l2jserver.model.world.character.event.CharacterLeaveWorldEvent; import com.l2jserver.model.world.character.event.CharacterLeaveWorldEvent;
@@ -76,6 +89,12 @@ import com.l2jserver.util.geometry.Point3D;
BroadcastService.class }) BroadcastService.class })
public class CharacterServiceImpl extends AbstractService implements public class CharacterServiceImpl extends AbstractService implements
CharacterService { CharacterService {
/**
* The logger
*/
private static final Logger log = LoggerFactory
.getLogger(CharacterServiceImpl.class);
/** /**
* The {@link BroadcastService} * The {@link BroadcastService}
*/ */
@@ -104,11 +123,19 @@ public class CharacterServiceImpl extends AbstractService implements
* The {@link GameGuardService} * The {@link GameGuardService}
*/ */
private final GameGuardService ggService; private final GameGuardService ggService;
/**
* The {@link CharacterDAO}
*/
private final CharacterDAO characterDao;
/** /**
* The {@link ItemDAO} * The {@link ItemDAO}
*/ */
private final ItemDAO itemDao; private final ItemDAO itemDao;
private final CharacterIDProvider charIdProvider;
private final CharacterTemplateIDProvider charTemplateIdProvider;
// /** // /**
// * The {@link AIService} // * The {@link AIService}
// */ // */
@@ -118,7 +145,10 @@ public class CharacterServiceImpl extends AbstractService implements
public CharacterServiceImpl(BroadcastService broadcastService, public CharacterServiceImpl(BroadcastService broadcastService,
WorldEventDispatcher eventDispatcher, ChatService chatService, WorldEventDispatcher eventDispatcher, ChatService chatService,
NetworkService networkService, SpawnService spawnService, 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.broadcastService = broadcastService;
this.eventDispatcher = eventDispatcher; this.eventDispatcher = eventDispatcher;
this.chatService = chatService; this.chatService = chatService;
@@ -126,7 +156,60 @@ public class CharacterServiceImpl extends AbstractService implements
this.spawnService = spawnService; this.spawnService = spawnService;
this.npcService = npcService; this.npcService = npcService;
this.ggService = ggService; this.ggService = ggService;
this.characterDao = characterDao;
this.itemDao = itemDao; 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 @Override