Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Utilize the MakeCharInfo.img data in the WZ files #218

Merged
merged 2 commits into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 21 additions & 16 deletions src/main/java/client/creator/CharacterFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,19 @@ protected synchronized static int createNewCharacter(Client c, String name, int
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);

newchar.setLevel(recipe.getLevel());
newchar.setJob(recipe.getJob());
newchar.setMapId(recipe.getMap());

Inventory equipped = newchar.getInventory(InventoryType.EQUIPPED);
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);

newCharacter.setLevel(recipe.getLevel());
newCharacter.setJob(recipe.getJob());
newCharacter.setMapId(recipe.getMap());

Inventory equipped = newCharacter.getInventory(InventoryType.EQUIPPED);
ItemInformationProvider ii = ItemInformationProvider.getInstance();

int top = recipe.getTop(), bottom = recipe.getBottom(), shoes = recipe.getShoes(), weapon = recipe.getWeapon();
Expand Down Expand Up @@ -88,12 +88,17 @@ protected synchronized static int createNewCharacter(Client c, String name, int
equipped.addItemFromDB(eq_weapon.copy());
}

if (!newchar.insertNewChar(recipe)) {
if (!MakeCharInfoHandler.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);

Expand Down
140 changes: 140 additions & 0 deletions src/main/java/client/creator/MakeCharInfo.java
Original file line number Diff line number Diff line change
@@ -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.ArrayList;
import java.util.List;

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 List<Integer> charFaces = new ArrayList<>();
private final List<Integer> charHairs = new ArrayList<>();
private final List<Integer> charHairColors = new ArrayList<>();
private final List<Integer> charSkins = new ArrayList<>();
private final List<Integer> charTops = new ArrayList<>();
private final List<Integer> charBottoms = new ArrayList<>();
private final List<Integer> charShoes = new ArrayList<>();
private final List<Integer> charWeapons = new ArrayList<>();
Silwhoon marked this conversation as resolved.
Show resolved Hide resolved

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 changes: 41 additions & 0 deletions src/main/java/client/creator/MakeCharInfoHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package client.creator;

import client.Character;
import provider.Data;
import provider.DataProviderFactory;
import provider.wz.WZFiles;

public class MakeCharInfoHandler {
Silwhoon marked this conversation as resolved.
Show resolved Hide resolved
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);
}
}
3 changes: 1 addition & 2 deletions src/main/java/client/creator/novice/BeginnerCreator.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ private static void giveItem(CharacterFactoryRecipe recipe, int itemid, int quan
}

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));
}
}
3 changes: 1 addition & 2 deletions src/main/java/client/creator/novice/LegendCreator.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ private static void giveItem(CharacterFactoryRecipe recipe, int itemid, int quan
}

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));
}
}
3 changes: 1 addition & 2 deletions src/main/java/client/creator/novice/NoblesseCreator.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ private static void giveItem(CharacterFactoryRecipe recipe, int itemid, int quan
}

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));
}
}
40 changes: 1 addition & 39 deletions src/main/java/net/server/handlers/login/CreateCharHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,43 +25,14 @@
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();
Expand All @@ -76,15 +47,6 @@ public final void handlePacket(InPacket p, Client c) {
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
Expand Down
Loading