Merge pull request #218 from Silwhoon/makecharinfo #minor
Utilize the MakeCharInfo.img data in the WZ files
This commit is contained in:
@@ -47,19 +47,19 @@ public abstract class CharacterFactory {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Character newchar = Character.getDefault(c);
|
||||
newchar.setWorld(c.getWorld());
|
||||
newchar.setSkinColor(SkinColor.getById(skin));
|
||||
newchar.setGender(gender);
|
||||
newchar.setName(name);
|
||||
newchar.setHair(hair);
|
||||
newchar.setFace(face);
|
||||
Character newCharacter = Character.getDefault(c);
|
||||
newCharacter.setWorld(c.getWorld());
|
||||
newCharacter.setSkinColor(SkinColor.getById(skin));
|
||||
newCharacter.setGender(gender);
|
||||
newCharacter.setName(name);
|
||||
newCharacter.setHair(hair);
|
||||
newCharacter.setFace(face);
|
||||
|
||||
newchar.setLevel(recipe.getLevel());
|
||||
newchar.setJob(recipe.getJob());
|
||||
newchar.setMapId(recipe.getMap());
|
||||
newCharacter.setLevel(recipe.getLevel());
|
||||
newCharacter.setJob(recipe.getJob());
|
||||
newCharacter.setMapId(recipe.getMap());
|
||||
|
||||
Inventory equipped = newchar.getInventory(InventoryType.EQUIPPED);
|
||||
Inventory equipped = newCharacter.getInventory(InventoryType.EQUIPPED);
|
||||
ItemInformationProvider ii = ItemInformationProvider.getInstance();
|
||||
|
||||
int top = recipe.getTop(), bottom = recipe.getBottom(), shoes = recipe.getShoes(), weapon = recipe.getWeapon();
|
||||
@@ -88,12 +88,17 @@ public abstract class CharacterFactory {
|
||||
equipped.addItemFromDB(eq_weapon.copy());
|
||||
}
|
||||
|
||||
if (!newchar.insertNewChar(recipe)) {
|
||||
if (!MakeCharInfoValidator.isNewCharacterValid(newCharacter)) {
|
||||
log.warn("Owner from account {} tried to packet edit in character creation", c.getAccountName());
|
||||
return -2;
|
||||
}
|
||||
c.sendPacket(PacketCreator.addNewCharEntry(newchar));
|
||||
|
||||
Server.getInstance().createCharacterEntry(newchar);
|
||||
if (!newCharacter.insertNewChar(recipe)) {
|
||||
return -2;
|
||||
}
|
||||
c.sendPacket(PacketCreator.addNewCharEntry(newCharacter));
|
||||
|
||||
Server.getInstance().createCharacterEntry(newCharacter);
|
||||
Server.getInstance().broadcastGMMessage(c.getWorld(), PacketCreator.sendYellowTip("[New Char]: " + c.getAccountName() + " has created a new character with IGN " + name));
|
||||
log.info("Account {} created chr with name {}", c.getAccountName(), name);
|
||||
|
||||
|
||||
140
src/main/java/client/creator/MakeCharInfo.java
Normal file
140
src/main/java/client/creator/MakeCharInfo.java
Normal file
@@ -0,0 +1,140 @@
|
||||
package client.creator;
|
||||
|
||||
import client.Character;
|
||||
import client.Job;
|
||||
import client.inventory.InventoryType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import provider.Data;
|
||||
import provider.DataTool;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class MakeCharInfo {
|
||||
private static final Logger log = LoggerFactory.getLogger(MakeCharInfo.class);
|
||||
private static final String FACE_ID = "0";
|
||||
private static final String HAIR_ID = "1";
|
||||
private static final String HAIR_COLOR_ID = "2";
|
||||
private static final String SKIN_ID = "3";
|
||||
private static final String TOP_ID = "4";
|
||||
private static final String BOTTOM_ID = "5";
|
||||
private static final String SHOE_ID = "6";
|
||||
private static final String WEAPON_ID = "7";
|
||||
|
||||
private final Set<Integer> charFaces = new HashSet<>();
|
||||
private final Set<Integer> charHairs = new HashSet<>();
|
||||
private final Set<Integer> charHairColors = new HashSet<>();
|
||||
private final Set<Integer> charSkins = new HashSet<>();
|
||||
private final Set<Integer> charTops = new HashSet<>();
|
||||
private final Set<Integer> charBottoms = new HashSet<>();
|
||||
private final Set<Integer> charShoes = new HashSet<>();
|
||||
private final Set<Integer> charWeapons = new HashSet<>();
|
||||
|
||||
public MakeCharInfo(Data charInfoData) {
|
||||
for (Data data : charInfoData.getChildren()) {
|
||||
switch (data.getName()) {
|
||||
case FACE_ID -> {
|
||||
for (Data faceData : data) {
|
||||
charFaces.add(DataTool.getInt(faceData));
|
||||
}
|
||||
}
|
||||
case HAIR_ID -> {
|
||||
for (Data hairData : data) {
|
||||
charHairs.add(DataTool.getInt(hairData));
|
||||
}
|
||||
}
|
||||
case HAIR_COLOR_ID -> {
|
||||
for (Data hairColorData : data) {
|
||||
charHairColors.add(DataTool.getInt(hairColorData));
|
||||
}
|
||||
}
|
||||
case SKIN_ID -> {
|
||||
for (Data skinData : data) {
|
||||
charSkins.add(DataTool.getInt(skinData));
|
||||
}
|
||||
}
|
||||
case TOP_ID -> {
|
||||
for (Data topData : data) {
|
||||
charTops.add(DataTool.getInt(topData));
|
||||
}
|
||||
}
|
||||
case BOTTOM_ID -> {
|
||||
for (Data bottomData : data) {
|
||||
charBottoms.add(DataTool.getInt(bottomData));
|
||||
}
|
||||
}
|
||||
case SHOE_ID -> {
|
||||
for (Data shoeData : data) {
|
||||
charShoes.add(DataTool.getInt(shoeData));
|
||||
}
|
||||
}
|
||||
case WEAPON_ID -> {
|
||||
for (Data weaponData : data) {
|
||||
charWeapons.add(DataTool.getInt(weaponData));
|
||||
}
|
||||
}
|
||||
default -> log.error("Unhandled node inside MakeCharInfo.img.xml: '" + data.getName() + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean verifyFaceId(int id) {
|
||||
return this.charFaces.contains(id);
|
||||
}
|
||||
|
||||
public boolean verifyHairId(int id) {
|
||||
if (id % 10 != 0) {
|
||||
return this.charHairs.contains(id - (id % 10));
|
||||
}
|
||||
return this.charHairs.contains(id);
|
||||
}
|
||||
|
||||
public boolean verifyHairColorId(int id) {
|
||||
return this.charHairColors.contains(id % 10);
|
||||
}
|
||||
|
||||
public boolean verifySkinId(int id) {
|
||||
return this.charSkins.contains(id);
|
||||
}
|
||||
|
||||
public boolean verifyTopId(int id) {
|
||||
return this.charTops.contains(id);
|
||||
}
|
||||
|
||||
public boolean verifyBottomId(int id) {
|
||||
return this.charBottoms.contains(id);
|
||||
}
|
||||
|
||||
public boolean verifyShoeId(int id) {
|
||||
return this.charShoes.contains(id);
|
||||
}
|
||||
|
||||
public boolean verifyWeaponId(int id) {
|
||||
return this.charWeapons.contains(id);
|
||||
}
|
||||
|
||||
public boolean verifyCharacter(Character character) {
|
||||
if (!verifyFaceId(character.getFace())) return false;
|
||||
if (!verifyHairId(character.getHair())) return false;
|
||||
if (!verifyHairColorId(character.getHair())) return false;
|
||||
if (!verifySkinId(character.getSkinColor().getId())) return false;
|
||||
|
||||
// Here we only verify the equipment if the character that's being created is of type 'Beginner'
|
||||
// This is because when the Maple Life A or Maple Life B items are used, the client does not send any data
|
||||
// regarding what equipment the character should be wearing (as it's all handled server-side)
|
||||
Job characterJob = character.getJob();
|
||||
if (characterJob == Job.BEGINNER || characterJob == Job.NOBLESSE || characterJob == Job.LEGEND) {
|
||||
if (!verifyTopId(character.getInventory(InventoryType.EQUIPPED).getItem((short) -5).getItemId()))
|
||||
return false;
|
||||
if (!verifyBottomId(character.getInventory(InventoryType.EQUIPPED).getItem((short) -6).getItemId()))
|
||||
return false;
|
||||
if (!verifyShoeId(character.getInventory(InventoryType.EQUIPPED).getItem((short) -7).getItemId()))
|
||||
return false;
|
||||
if (!verifyWeaponId(character.getInventory(InventoryType.EQUIPPED).getItem((short) -11).getItemId()))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
41
src/main/java/client/creator/MakeCharInfoValidator.java
Normal file
41
src/main/java/client/creator/MakeCharInfoValidator.java
Normal file
@@ -0,0 +1,41 @@
|
||||
package client.creator;
|
||||
|
||||
import client.Character;
|
||||
import provider.Data;
|
||||
import provider.DataProviderFactory;
|
||||
import provider.wz.WZFiles;
|
||||
|
||||
public class MakeCharInfoValidator {
|
||||
private static final MakeCharInfo charFemale;
|
||||
private static final MakeCharInfo charMale;
|
||||
private static final MakeCharInfo orientCharFemale;
|
||||
private static final MakeCharInfo orientCharMale;
|
||||
private static final MakeCharInfo premiumCharFemale;
|
||||
private static final MakeCharInfo premiumCharMale;
|
||||
|
||||
static {
|
||||
Data data = DataProviderFactory.getDataProvider(WZFiles.ETC).getData("MakeCharInfo.img");
|
||||
charFemale = new MakeCharInfo(data.getChildByPath("Info/CharFemale"));
|
||||
charMale = new MakeCharInfo(data.getChildByPath("Info/CharMale"));
|
||||
orientCharFemale = new MakeCharInfo(data.getChildByPath("OrientCharFemale"));
|
||||
orientCharMale = new MakeCharInfo(data.getChildByPath("OrientCharMale"));
|
||||
premiumCharFemale = new MakeCharInfo(data.getChildByPath("PremiumCharFemale"));
|
||||
premiumCharMale = new MakeCharInfo(data.getChildByPath("PremiumCharMale"));
|
||||
}
|
||||
|
||||
private static MakeCharInfo getMakeCharInfo(Character character) {
|
||||
return switch (character.getJob()) {
|
||||
case BEGINNER, WARRIOR, MAGICIAN, BOWMAN, THIEF, PIRATE -> character.isMale() ? charMale : charFemale;
|
||||
case NOBLESSE -> character.isMale() ? premiumCharMale : premiumCharFemale;
|
||||
case LEGEND -> character.isMale() ? orientCharMale : orientCharFemale;
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
public static boolean isNewCharacterValid(Character character) {
|
||||
MakeCharInfo makeCharInfo = getMakeCharInfo(character);
|
||||
if (makeCharInfo == null) return false;
|
||||
|
||||
return makeCharInfo.verifyCharacter(character);
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,6 @@ public class BeginnerCreator extends CharacterFactory {
|
||||
}
|
||||
|
||||
public static int createCharacter(Client c, String name, int face, int hair, int skin, int top, int bottom, int shoes, int weapon, int gender) {
|
||||
int status = createNewCharacter(c, name, face, hair, skin, gender, createRecipe(Job.BEGINNER, 1, MapId.MUSHROOM_TOWN, top, bottom, shoes, weapon));
|
||||
return status;
|
||||
return createNewCharacter(c, name, face, hair, skin, gender, createRecipe(Job.BEGINNER, 1, MapId.MUSHROOM_TOWN, top, bottom, shoes, weapon));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,6 @@ public class LegendCreator extends CharacterFactory {
|
||||
}
|
||||
|
||||
public static int createCharacter(Client c, String name, int face, int hair, int skin, int top, int bottom, int shoes, int weapon, int gender) {
|
||||
int status = createNewCharacter(c, name, face, hair, skin, gender, createRecipe(Job.LEGEND, 1, MapId.ARAN_TUTORIAL_START, top, bottom, shoes, weapon));
|
||||
return status;
|
||||
return createNewCharacter(c, name, face, hair, skin, gender, createRecipe(Job.LEGEND, 1, MapId.ARAN_TUTORIAL_START, top, bottom, shoes, weapon));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,6 @@ public class NoblesseCreator extends CharacterFactory {
|
||||
}
|
||||
|
||||
public static int createCharacter(Client c, String name, int face, int hair, int skin, int top, int bottom, int shoes, int weapon, int gender) {
|
||||
int status = createNewCharacter(c, name, face, hair, skin, gender, createRecipe(Job.NOBLESSE, 1, MapId.STARTING_MAP_NOBLESSE, top, bottom, shoes, weapon));
|
||||
return status;
|
||||
return createNewCharacter(c, name, face, hair, skin, gender, createRecipe(Job.NOBLESSE, 1, MapId.STARTING_MAP_NOBLESSE, top, bottom, shoes, weapon));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,46 +95,6 @@ public class ItemId {
|
||||
public static final int BEGINNERS_GUIDE = 4161001;
|
||||
public static final int LEGENDS_GUIDE = 4161048;
|
||||
public static final int NOBLESSE_GUIDE = 4161047;
|
||||
public static final int SWORD = 1302000; // Weapon
|
||||
public static final int HAND_AXE = 1312004;
|
||||
public static final int WOODEN_CLUB = 1322005;
|
||||
public static final int BASIC_POLEARM = 1442079;
|
||||
public static final int WHITE_UNDERSHIRT = 1040002; // Top
|
||||
public static final int UNDERSHIRT = 1040006;
|
||||
public static final int GREY_TSHIRT = 1040010;
|
||||
public static final int WHITE_TUBETOP = 1041002;
|
||||
public static final int YELLOW_TSHIRT = 1041006;
|
||||
public static final int GREEN_TSHIRT = 1041010;
|
||||
public static final int RED_STRIPED_TOP = 1041011;
|
||||
public static final int SIMPLE_WARRIOR_TOP = 1042167;
|
||||
public static final int BLUE_JEAN_SHORTS = 1060002; // Bottom
|
||||
public static final int BROWN_COTTON_SHORTS = 1060006;
|
||||
public static final int RED_MINISKIRT = 1061002;
|
||||
public static final int INDIGO_MINISKIRT = 1061008;
|
||||
public static final int SIMPLE_WARRIOR_PANTS = 1062115;
|
||||
public static final int RED_RUBBER_BOOTS = 1072001;
|
||||
public static final int LEATHER_SANDALS = 1072005;
|
||||
public static final int YELLOW_RUBBER_BOOTS = 1072037;
|
||||
public static final int BLUE_RUBBER_BOOTS = 1072038;
|
||||
public static final int AVERAGE_MUSASHI_SHOES = 1072383;
|
||||
public static final int BLACK_TOBEN = 30000; // Hair
|
||||
public static final int ZETA = 30010;
|
||||
public static final int BLACK_REBEL = 30020;
|
||||
public static final int BLACK_BUZZ = 30030;
|
||||
public static final int BLACK_SAMMY = 31000;
|
||||
public static final int BLACK_EDGY = 31040;
|
||||
public static final int BLACK_CONNIE = 31050;
|
||||
public static final int MOTIVATED_LOOK_M = 20000; // Face
|
||||
public static final int PERPLEXED_STARE = 20001;
|
||||
public static final int LEISURE_LOOK_M = 20002;
|
||||
public static final int MOTIVATED_LOOK_F = 21000;
|
||||
public static final int FEARFUL_STARE_M = 21001;
|
||||
public static final int LEISURE_LOOK_F = 21002;
|
||||
public static final int FEARFUL_STARE_F = 21201;
|
||||
public static final int PERPLEXED_STARE_HAZEL = 20401;
|
||||
public static final int LEISURE_LOOK_HAZEL = 20402;
|
||||
public static final int MOTIVATED_LOOK_AMETHYST = 21700;
|
||||
public static final int MOTIVATED_LOOK_BLUE = 20100;
|
||||
|
||||
// Warrior
|
||||
public static final int RED_HWARANG_SHIRT = 1040021;
|
||||
|
||||
@@ -25,43 +25,14 @@ import client.Client;
|
||||
import client.creator.novice.BeginnerCreator;
|
||||
import client.creator.novice.LegendCreator;
|
||||
import client.creator.novice.NoblesseCreator;
|
||||
import constants.id.ItemId;
|
||||
import net.AbstractPacketHandler;
|
||||
import net.packet.InPacket;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import tools.PacketCreator;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public final class CreateCharHandler extends AbstractPacketHandler {
|
||||
private static final Logger log = LoggerFactory.getLogger(CreateCharHandler.class);
|
||||
|
||||
private final static Set<Integer> IDs = new HashSet<>(Arrays.asList(
|
||||
ItemId.SWORD, ItemId.HAND_AXE, ItemId.WOODEN_CLUB, ItemId.BASIC_POLEARM,// weapons
|
||||
ItemId.WHITE_UNDERSHIRT, ItemId.UNDERSHIRT, ItemId.GREY_TSHIRT, ItemId.WHITE_TUBETOP, ItemId.YELLOW_TSHIRT,
|
||||
ItemId.GREEN_TSHIRT, ItemId.RED_STRIPED_TOP, ItemId.SIMPLE_WARRIOR_TOP,// bottom
|
||||
ItemId.BLUE_JEAN_SHORTS, ItemId.BROWN_COTTON_SHORTS, ItemId.RED_MINISKIRT, ItemId.INDIGO_MINISKIRT,
|
||||
ItemId.SIMPLE_WARRIOR_PANTS, // top
|
||||
ItemId.RED_RUBBER_BOOTS, ItemId.LEATHER_SANDALS, ItemId.YELLOW_RUBBER_BOOTS, ItemId.BLUE_RUBBER_BOOTS,
|
||||
ItemId.AVERAGE_MUSASHI_SHOES,// shoes
|
||||
ItemId.BLACK_TOBEN, ItemId.ZETA, ItemId.BLACK_REBEL, ItemId.BLACK_BUZZ, ItemId.BLACK_SAMMY,
|
||||
ItemId.BLACK_EDGY, ItemId.BLACK_CONNIE,// hair
|
||||
ItemId.MOTIVATED_LOOK_M, ItemId.PERPLEXED_STARE, ItemId.LEISURE_LOOK_M, ItemId.MOTIVATED_LOOK_F,
|
||||
ItemId.FEARFUL_STARE_M, ItemId.LEISURE_LOOK_F, ItemId.FEARFUL_STARE_F, ItemId.PERPLEXED_STARE_HAZEL,
|
||||
ItemId.LEISURE_LOOK_HAZEL, ItemId.MOTIVATED_LOOK_AMETHYST, ItemId.MOTIVATED_LOOK_BLUE //face
|
||||
//#NeverTrustStevenCode
|
||||
));
|
||||
|
||||
private static boolean isLegal(Integer toCompare) {
|
||||
return IDs.contains(toCompare);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void handlePacket(InPacket p, Client c) {
|
||||
public void handlePacket(InPacket p, Client c) {
|
||||
String name = p.readString();
|
||||
int job = p.readInt();
|
||||
int face = p.readInt();
|
||||
@@ -76,15 +47,6 @@ public final class CreateCharHandler extends AbstractPacketHandler {
|
||||
int weapon = p.readInt();
|
||||
int gender = p.readByte();
|
||||
|
||||
int[] items = new int[]{weapon, top, bottom, shoes, hair, face};
|
||||
for (int item : items) {
|
||||
if (!isLegal(item)) {
|
||||
log.warn("Owner from account {} tried to packet edit in chr creation", c.getAccountName());
|
||||
c.disconnect(true, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int status;
|
||||
switch (job) {
|
||||
case 0: // Knights of Cygnus
|
||||
|
||||
Reference in New Issue
Block a user