package handling.login.handler; import client.ClientRedirector; import client.LoginCrypto; import client.MapleCharacter; import client.MapleCharacterUtil; import client.MapleClient; import client.MapleJob; import client.PartTimeJob; import client.Skill; import client.SkillEntry; import client.SkillFactory; import client.inventory.Item; import client.inventory.MapleInventory; import client.inventory.MapleInventoryType; import constants.JobConstants; import constants.ServerConfig; import constants.ServerConstants; import constants.WorldConstants; import database.DatabaseConnection; import handling.channel.ChannelServer; import handling.login.LoginInformationProvider; import handling.login.LoginInformationProvider.JobType; import handling.login.LoginServer; import handling.login.LoginWorker; import handling.world.World; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import server.MapleItemInformationProvider; import server.quest.MapleQuest; import tools.FileoutputUtil; import tools.Triple; import tools.data.LittleEndianAccessor; import tools.packet.CField; import tools.packet.CWvsContext; import tools.packet.LoginPacket; import tools.packet.PacketHelper; public class CharLoginHandler { private static boolean loginFailCount(final MapleClient c) { c.loginAttempt++; return c.loginAttempt > 4; } public static void handleAuthRequest(final LittleEndianAccessor slea, final MapleClient c) { //System.out.println("Sending response to client."); int request = slea.readInt(); int response; response = ((request >> 5) << 5) + (((((request & 0x1F) >> 3) ^ 2) << 3) + (7 - (request & 7))); response |= ((request >> 7) << 7); response -= 1; //-1 again on v143 c.getSession().write(LoginPacket.sendAuthResponse(response)); } public static final void login(final LittleEndianAccessor slea, final MapleClient c) { slea.skip(22); String login = slea.readMapleAsciiString()/*.replace("NP12:auth06:5:0:","")*/; String pwd = slea.readMapleAsciiString(); final boolean ipBan = c.hasBannedIP(); final boolean macBan = c.hasBannedMac(); int loginok = c.login(login, pwd, ipBan || macBan); final Calendar tempbannedTill = c.getTempBanCalendar(); String errorInfo = null; if (loginok == 0 && (ipBan || macBan) && !c.isGM()) { //被封鎖IP或MAC的非GM角色成功登入處理 loginok = 3; if (macBan) { // this is only an ipban o.O" - maybe we should refactor this a bit so it's more readable MapleCharacter.ban(c.getSession().getRemoteAddress().toString().split(":")[0], "Enforcing account ban, account " + login, false, 4, false); } } else if (loginok == 0 && (c.getGender() == 10 || c.getSecondPassword() == null)) { //選擇性别並設置第二組密碼 // c.updateLoginState(MapleClient.CHOOSE_GENDER, c.getSessionIPAddress()); c.getSession().write(LoginPacket.genderNeeded()); return; } else if (loginok == 5) { //账号不存在 if (ServerConfig.isAutoRegister()) { if (AutoRegister.createAccount(login, pwd, c.getSession().getRemoteAddress().toString())) { errorInfo = "註冊賬號成功。\r\n請重新輸入賬號密碼進入遊戲。"; } else { errorInfo = "註冊賬號失敗。"; } } else { errorInfo = "賬號註冊失敗,未開啟自動註冊功能,請到網站註冊賬號。"; } loginok = 1; } if (loginok != 0) { if (!loginFailCount(c)) { c.clearInformation(); c.getSession().write(LoginPacket.getLoginFailed(loginok)); if (errorInfo != null) { c.getSession().write(CWvsContext.broadcastMsg(1, errorInfo)); } } else { c.getSession().close(true); } } else if (tempbannedTill.getTimeInMillis() != 0) { if (!loginFailCount(c)) { c.clearInformation(); c.getSession().write(LoginPacket.getTempBan(PacketHelper.getTime(tempbannedTill.getTimeInMillis()), c.getBanReason())); } else { c.getSession().close(true); } } else { c.loginAttempt = 0; LoginWorker.registerClient(c); } } public static void ServerListRequest(final MapleClient c) { List<Triple<String, Integer, Boolean>> backgrounds = new LinkedList<>(); //boolean for randomize backgrounds.addAll(Arrays.asList(ServerConstants.backgrounds)); c.getSession().write(ServerConstants.MAPLE_TYPE == ServerConstants.MapleType.GLOBAL ? CField.spawnFlags(null) : LoginPacket.changeBackground(backgrounds)); for (WorldConstants.Option servers : WorldConstants.values()) { if (servers.show()) { c.getSession().write(LoginPacket.getServerList(servers)); if (ServerConstants.MAPLE_TYPE == ServerConstants.MapleType.GLOBAL) { c.getSession().write(LoginPacket.getWorldSelected(c)); } } } c.getSession().write(LoginPacket.getEndOfServerList()); boolean hasCharacters = false; for (int world = 0; world < WorldConstants.values().length; world++) { final List<MapleCharacter> chars = c.loadCharacters(world); if (chars != null) { hasCharacters = true; break; } } if (!hasCharacters) { c.getSession().write(LoginPacket.enableRecommended(WorldConstants.recommended)); } if (WorldConstants.recommended >= 0) { c.getSession().write(LoginPacket.sendRecommended(WorldConstants.recommended, WorldConstants.recommendedmsg)); } } public static void ServerStatusRequest(final MapleClient c) { // 0 = Select world normally // 1 = "Since there are many users, you may encounter some..." // 2 = "The concurrent users in this world have reached the max" final int numPlayer = LoginServer.getUsersOn(); final int userLimit = LoginServer.getUserLimit(); if (numPlayer >= userLimit) { c.getSession().write(LoginPacket.getServerStatus(2)); } else if (numPlayer * 2 >= userLimit) { c.getSession().write(LoginPacket.getServerStatus(1)); } else { c.getSession().write(LoginPacket.getServerStatus(0)); } } public static void CharlistRequest(final LittleEndianAccessor slea, final MapleClient c) { if (!c.isLoggedIn()) { c.getSession().close(true); return; } final int mode = slea.readByte(); //2? final int server; final int channel; if (mode == 0) { server = slea.readByte(); channel = slea.readByte() + 1; } else { slea.skip(1); String code = slea.readMapleAsciiString(); Map<String, ClientRedirector> redirectors = World.Redirector.getRedirectors(); ClientRedirector redirector; if (!redirectors.containsKey(code) || !redirectors.get(code).isLogined()) { if (!redirectors.get(code).isLogined()) { redirectors.remove(code); } c.getSession().close(true); return; } else { redirector = redirectors.remove(code); } server = redirector.getWorld(); channel = redirector.getChannel(); } if (!World.isChannelAvailable(channel, server) || !WorldConstants.isExists(server)) { c.getSession().write(LoginPacket.getLoginFailed(10)); //cannot process so many return; } if (!WorldConstants.getById(server).isAvailable() && !(c.isGM() && server == WorldConstants.gmserver)) { c.getSession().write(CWvsContext.broadcastMsg(1, "這個伺服器暫時無法連接. \r\n請嘗試連接其他伺服器.")); c.getSession().write(LoginPacket.getLoginFailed(1)); //Shows no message, but it is used to unstuck return; } System.out.println("用戶端地址: " + c.getSession().getRemoteAddress().toString().split(":")[0] + " 連接到伺服器: " + server + " 頻道: " + channel + ""); final List<MapleCharacter> chars = c.loadCharacters(server); if (chars != null && ChannelServer.getInstance(channel) != null) { c.setWorld(server); c.setChannel(channel); if (ServerConstants.MAPLE_TYPE == ServerConstants.MapleType.GLOBAL || mode == 1) { c.getSession().write(LoginPacket.getSecondAuthSuccess(c)); c.getSession().write(LoginPacket.getChannelSelected()); } c.getSession().write(LoginPacket.getCharList(c.getSecondPassword(), c.getCharacterPos(), chars, c.getCharacterSlots())); } else { c.getSession().close(true); } } public static void changeCharPosition(final LittleEndianAccessor slea, final MapleClient c) { slea.readInt(); slea.readByte(); int count = slea.readInt(); if (count != c.getCharacterPos().size()) { System.out.println("角色位置更變出錯: 更變個數與實際不符"); } final ArrayList<Integer> newCharPos = new ArrayList(); for (int i = 0; i < count; i++) { int pos = slea.readInt(); if (c.getCharacterPos().contains(pos)) { newCharPos.add(pos); } else { System.out.println("角色位置更變出錯: 非本賬號的角色ID"); return; } } c.updateCharacterPos(newCharPos); } public static void updateCCards(final LittleEndianAccessor slea, final MapleClient c) { if (slea.available() != 36 || !c.isLoggedIn()) { c.getSession().close(true); return; } final Map<Integer, Integer> cids = new LinkedHashMap<>(); for (int i = 1; i <= 9; i++) { final int charId = slea.readInt(); if ((!c.login_Auth(charId) && charId != 0) || ChannelServer.getInstance(c.getChannel()) == null || !WorldConstants.isExists(c.getWorld())) { c.getSession().close(true); return; } cids.put(i, charId); } c.updateCharacterCards(cids); } public static void CheckCharName(final String name, final MapleClient c) { LoginInformationProvider li = LoginInformationProvider.getInstance(); boolean nameUsed = true; if (MapleCharacterUtil.canCreateChar(name, c.isGM())) { nameUsed = false; } if (li.isForbiddenName(name) && !c.isGM()) { nameUsed = false; } c.getSession().write(LoginPacket.charNameResponse(name, nameUsed)); } public static void CreateChar2Pw(final LittleEndianAccessor slea, final MapleClient c) { final String Secondpw_Client = slea.readMapleAsciiString(); if (!c.isLoggedIn() || loginFailCount(c) || c.getSecondPassword() == null) { c.getSession().close(true); return; } byte state = 0; if (!c.CheckSecondPassword(Secondpw_Client)) { // Wrong Password state = 20; } c.getSession().write(LoginPacket.createCharResponse(state)); // 驗證碼 // c.getSession().write(LoginPacket.createCharCheckCode(CheckCodeImageCreator.createCheckCode().getRight(), (byte) 0, (byte) 1, (byte) 1, (byte) 0)); } public static void CreateChar(final LittleEndianAccessor slea, final MapleClient c) { String name; byte gender, skin, unk; short subcategory; int face, hair, hairColor = -1, hat = -1, top, bottom = -1, glove = -1, shoes, weapon, cape = -1, faceMark = -1, ears = -1, tail = -1, shield = -1; JobType job; name = slea.readMapleAsciiString(); if (!MapleCharacterUtil.canCreateChar(name, false)) { System.out.println("非法創建角色名: " + name); return; } int keymapType = slea.readInt(); //按鍵模式: 0-基本模式; 1-進階模式 slea.readInt(); // int job_type = slea.readInt(); job = JobType.getByType(job_type); if (job == null) { System.out.println("發現新職業類型: " + job_type); return; } for (JobConstants.LoginJob j : JobConstants.LoginJob.values()) { if (j.getJobType() == job_type) { if (j.getFlag() != JobConstants.LoginJob.JobFlag.開啟.getFlag()) { System.out.println("未開放的職業被嘗試創建"); return; } } } subcategory = slea.readShort(); gender = slea.readByte(); skin = slea.readByte(); unk = slea.readByte(); //6/7/8/9 face = slea.readInt(); hair = slea.readInt(); // if (job.hairColor) { // hairColor = slea.readInt(); // } // if (job.skinColor) { // slea.readInt(); // } if (job.faceMark) { faceMark = slea.readInt(); } if (job.ears) { ears = slea.readInt(); } if (job.tail) { tail = slea.readInt(); } if (job.hat) { hat = slea.readInt(); } top = slea.readInt(); if (job.bottom) { bottom = slea.readInt(); } if (job.cape) { cape = slea.readInt(); } shoes = slea.readInt(); if (job.glove) { glove = slea.readInt(); } weapon = slea.readInt(); if (slea.available() >= 4) { shield = slea.readInt(); } // int index = 0; // boolean noSkin = job == JobType.惡魔 || job == JobType.精靈遊俠 || job == JobType.蒼龍俠客; // int[] items = new int[]{face, hair, hairColor, noSkin ? -1 : skin, faceMark, hat, top, bottom, cape, shoes, weapon, shield}; // for (int i : items) { // if (i > -1) { // if (!LoginInformationProvider.getInstance().isEligibleItem(gender, index, job.type, i)) { // System.out.println(gender + " | " + index + " | " + job.type + " | " + i); // return; // } // index++; // } //讀取創建角色默認配置 MapleCharacter newchar = MapleCharacter.getDefault(c, job); newchar.setWorld((byte) c.getWorld()); newchar.setFace(face); newchar.setSecondFace(face); if (hairColor < 0) { hairColor = 0; } if (job != JobType.米哈逸) { hair += hairColor; } newchar.setHair(hair); newchar.setSecondHair(hair); if (job == JobType.天使破壞者) { newchar.setSecondFace(21173); newchar.setSecondHair(37141); } else if (job == JobType.神之子) { newchar.setSecondFace(21290); newchar.setSecondHair(37623); } newchar.setGender(gender); newchar.setName(name); newchar.setSkinColor(skin); if (faceMark < 0) { faceMark = 0; } newchar.setFaceMarking(faceMark); int[] wrongEars = {1004062, 1004063, 1004064}; int[] correctEars = {5010116, 5010117, 5010118}; int[] wrongTails = {1102661, 1102662, 1102663}; int[] correctTails = {5010119, 5010120, 5010121}; for (int i = 0; i < wrongEars.length; i++) { if (ears == wrongEars[i]) { ears = correctEars[i]; } } for (int i = 0; i < wrongTails.length; i++) { if (tail == wrongTails[i]) { tail = correctTails[i]; } } if (ears < 0) { ears = 0; } newchar.setEars(ears); if (tail < 0) { tail = 0; } newchar.setTail(tail); final MapleItemInformationProvider li = MapleItemInformationProvider.getInstance(); final MapleInventory equip = newchar.getInventory(MapleInventoryType.EQUIPPED); Item item; //-1 Hat | -2 Face | -3 Eye acc | -4 Ear acc | -5 Topwear //-6 Bottom | -7 Shoes | -8 glove | -9 Cape | -10 Shield | -11 Weapon //todo check zero's beta weapon slot int[][] equips = new int[][]{{hat, -1}, {top, -5}, {bottom, -6}, {cape, -9}, {shoes, -7}, {glove, -8}, {weapon, -11}, {shield, -10}}; for (int[] i : equips) { if (i[0] > 0) { item = li.getEquipById(i[0]); item.setPosition((byte) i[1]); item.setGMLog("創建角色獲得, 時間 " + FileoutputUtil.CurrentReadable_Time()); equip.addFromDB(item); } } // Additional skills for all first job classes. Some skills are not added by default, // so adding the skill ID here between the {}, will give the skills you entered to the desired job. int[][] skills = new int[][]{ {30000074/*自由精神*/},//末日反抗軍Resistance {1281/*回歸楓之谷*/},//冒險家Explorer {10000252/*元素位移*/, 10001244/*元素狂刃*/, 10001254/*元素閃現*/},//皇家騎士團Cygnus {/*20000194找回的記憶*/},//狂狼勇士Aran {20010022/*龍飛行*/},//龍魔導士Evan {}, //精靈遊俠Mercedes {},//惡魔Demon {},//幻影俠盜Phantom {},//影武者Dualblade {},//米哈逸Mihile {20040216/*光蝕*/, 20040217/*暗蝕*/, 20040219/*平衡*/, 20040220/*平衡*/, 20040221/*光明力量*/, 20041222/*星光順移*/},//夜光Luminous {},//凱撒Kaiser {60011216/*繼承人*/, 60011218/*魔法起重機*/, 60011220/*白日夢*/, 60011221/*配飾*/, 60011222/*魔法變身*/},//天使破壞者AngelicBuster {},//重炮指揮官Cannoneer {30020232/*蓄能系統*/, 30020234/*全能增幅 I*/, 30020240/*多樣化裝扮*/, 30021238/*刀舞*/},//傑諾Xenon {100000279/*時之意志*/, 100000282/*雙重打擊*/, 100001262/*神殿回歸*/, 100001263/*時之威能*/, 100001264/*聖靈神速*/, 100001265/*爆裂跳躍*/, 100001266/*爆裂衝刺*/, 100001268/*時之庇護*/},//神之子Zero {20051284/*閃現*/, 20050285/*精靈降臨1式*/},//隱月Eunwol {228/*草上飛*/},//蒼龍俠客Jett {40010000/*天賦的才能*/, 40010067/*攻守兼備*/, 40011023/*心刀*/},//劍豪Hayato {},//陰陽師Kanna {110001251/*管理連結技能*/}//幻獸師BeastTamer }; if (skills[job.type].length > 0) { final Map<Skill, SkillEntry> ss = new HashMap<>(); Skill s; for (int i : skills[job.type]) { s = SkillFactory.getSkill(i); int maxLevel = s.getMaxLevel(); if (maxLevel < 1) { maxLevel = s.getMasterLevel(); } ss.put(s, new SkillEntry((byte) 1, (byte) maxLevel, -1)); } if (job == JobType.神之子) { ss.put(SkillFactory.getSkill(101000103), new SkillEntry((byte) 8, (byte) 10, -1)); ss.put(SkillFactory.getSkill(101000203), new SkillEntry((byte) 8, (byte) 10, -1)); } if (job == JobType.幻獸師) { ss.put(SkillFactory.getSkill(110001511), new SkillEntry((byte) 0, (byte) 30, -1)); ss.put(SkillFactory.getSkill(110001512), new SkillEntry((byte) 0, (byte) 5, -1)); ss.put(SkillFactory.getSkill(110000513), new SkillEntry((byte) 0, (byte) 30, -1)); ss.put(SkillFactory.getSkill(110000515), new SkillEntry((byte) 0, (byte) 10, -1)); } newchar.changeSkillLevel_Skip(ss, false); } int[][] guidebooks = new int[][]{{4161001, 0}, {4161047, 1}, {4161048, 2000}, {4161052, 2001}, {4161054, 3}, {4161079, 2002}}; int guidebook = 0; for (int[] i : guidebooks) { if (newchar.getJob() == i[1]) { guidebook = i[0]; } else if (newchar.getJob() / 1000 == i[1]) { guidebook = i[0]; } } if (guidebook > 0) { newchar.getInventory(MapleInventoryType.ETC).addItem(new Item(guidebook, (byte) 0, (short) 1, (byte) 0)); } if (job == JobType.幻影俠盜) { newchar.getStat().maxhp = 850; newchar.getStat().hp = 140; newchar.getStat().maxmp = 805; newchar.getStat().mp = 38; } if (job == JobType.神之子) { newchar.setLevel((short) 100); newchar.getStat().str = 518; newchar.getStat().maxhp = 6910; newchar.getStat().hp = 6910; newchar.getStat().maxmp = 100; newchar.getStat().mp = 100; newchar.setRemainingSp(3, 0); //alpha newchar.setRemainingSp(3, 1); //beta } if (job == JobType.幻獸師) { newchar.setLevel((short) 10); newchar.getStat().maxhp = 567; newchar.getStat().hp = 551; newchar.getStat().maxmp = 270; newchar.getStat().mp = 263; newchar.setRemainingAp(45); newchar.setRemainingSp(3, 0); } if (ServerConfig.LOG_PACKETS) { FileoutputUtil.log(FileoutputUtil.Create_Character, "\r\n\r\n名字: " + name + "\r\n職業: " + job_type + "\r\n性別: " + gender + "\r\n皮膚: " + skin + "\r\n頭髮顏色: " + unk + "\r\n臉型: " + face + "\r\n髮型: " + hair + "\r\n臉飾: " + faceMark + "\r\n耳朵: " + ears + "\r\n尾巴: " + tail + "\r\n帽子: " + hat + "\r\n上衣: " + top + "\r\n褲子: " + bottom + "\r\n披風:" + cape + "\r\n鞋子: " + shoes + "\r\n手套: " + glove + "\r\n武器: " + weapon + "\r\n盾牌: " + shield + "\r\n\r\n" ); } if (MapleCharacterUtil.canCreateChar(name, c.isGM()) && (!LoginInformationProvider.getInstance().isForbiddenName(name) || c.isGM()) && (c.isGM() || c.canMakeCharacter(c.getWorld()))) { MapleCharacter.saveNewCharToDB(newchar, job, subcategory, keymapType); c.getSession().write(LoginPacket.addNewCharEntry(newchar, true)); c.createdChar(newchar.getId()); //newchar.newCharRewards(); } else { c.getSession().write(LoginPacket.addNewCharEntry(newchar, false)); } } public static void CreateUltimate(final LittleEndianAccessor slea, final MapleClient c) { if (!c.getPlayer().isGM() && (!c.isLoggedIn() || c.getPlayer() == null || c.getPlayer().getLevel() < 120 || c.getPlayer().getMapId() != 130000000 || c.getPlayer().getQuestStatus(20734) != 0 || c.getPlayer().getQuestStatus(20616) != 2 || !MapleJob.is皇家騎士團(c.getPlayer().getJob()) || !c.canMakeCharacter(c.getPlayer().getWorld()))) { c.getSession().write(CField.createUltimate(2)); //Character slots are full. Please purchase another slot from the Cash Shop. return; } //System.out.println(slea.toString()); final String name = slea.readMapleAsciiString(); final int job = slea.readInt(); //job ID final int face = slea.readInt(); final int hair = slea.readInt(); //No idea what are these used for: final int hat = slea.readInt(); final int top = slea.readInt(); final int glove = slea.readInt(); final int shoes = slea.readInt(); final int weapon = slea.readInt(); final byte gender = c.getPlayer().getGender(); //JobType errorCheck = JobType.Adventurer; //if (!LoginInformationProvider.getInstance().isEligibleItem(gender, 0, errorCheck.type, face)) { // c.getSession().write(CWvsContext.enableActions()); // return; //} JobType jobType = JobType.終極冒險家; MapleCharacter newchar = MapleCharacter.getDefault(c, jobType); newchar.setJob(job); newchar.setWorld(c.getPlayer().getWorld()); newchar.setFace(face); newchar.setHair(hair); newchar.setGender(gender); newchar.setName(name); newchar.setSkinColor((byte) 3); //troll newchar.setLevel((short) 50); newchar.getStat().str = (short) 4; newchar.getStat().dex = (short) 4; newchar.getStat().int_ = (short) 4; newchar.getStat().luk = (short) 4; newchar.setRemainingAp((short) 254); //49*5 + 25 - 16 newchar.setRemainingSp(job / 100 == 2 ? 128 : 122); //2 from job advancements. 120 from leveling. (mages get +6) newchar.getStat().maxhp += 150; //Beginner 10 levels newchar.getStat().maxmp += 125; switch (job) { case 110: case 120: case 130: newchar.getStat().maxhp += 600; //Job Advancement newchar.getStat().maxhp += 2000; //Levelup 40 times newchar.getStat().maxmp += 200; break; case 210: case 220: case 230: newchar.getStat().maxmp += 600; newchar.getStat().maxhp += 500; //Levelup 40 times newchar.getStat().maxmp += 2000; break; case 310: case 320: case 410: case 420: case 520: newchar.getStat().maxhp += 500; newchar.getStat().maxmp += 250; newchar.getStat().maxhp += 900; //Levelup 40 times newchar.getStat().maxmp += 600; break; case 510: newchar.getStat().maxhp += 500; newchar.getStat().maxmp += 250; newchar.getStat().maxhp += 450; //Levelup 20 times newchar.getStat().maxmp += 300; newchar.getStat().maxhp += 800; //Levelup 20 times newchar.getStat().maxmp += 400; break; default: return; } final Map<Skill, SkillEntry> ss = new HashMap<>(); ss.put(SkillFactory.getSkill(1074 + (job / 100)), new SkillEntry((byte) 5, (byte) 5, -1)); ss.put(SkillFactory.getSkill(80), new SkillEntry((byte) 1, (byte) 1, -1)); newchar.changeSkillLevel_Skip(ss, false); final MapleItemInformationProvider li = MapleItemInformationProvider.getInstance(); //TODO: Make this GMS - Like int[] items = new int[]{1142257, hat, top, shoes, glove, weapon, hat + 1, top + 1, shoes + 1, glove + 1, weapon + 1}; //brilliant = fine+1 for (byte i = 0; i < items.length; i++) { Item item = li.getEquipById(items[i]); item.setPosition((byte) (i + 1)); newchar.getInventory(MapleInventoryType.EQUIP).addFromDB(item); } newchar.getInventory(MapleInventoryType.USE).addItem(new Item(2000004, (byte) 0, (short) 200, (byte) 0)); if (MapleCharacterUtil.canCreateChar(name, c.isGM()) && (!LoginInformationProvider.getInstance().isForbiddenName(name) || c.isGM())) { MapleCharacter.saveNewCharToDB(newchar, jobType, (short) 0); MapleQuest.getInstance(20734).forceComplete(c.getPlayer(), 1101000); c.getSession().write(CField.createUltimate(0)); } else if (!LoginInformationProvider.getInstance().isForbiddenName(name) || c.isGM()) { c.getSession().write(CField.createUltimate(3)); //"You cannot use this name." } else { c.getSession().write(CField.createUltimate(1)); } } public static void DeleteChar(final LittleEndianAccessor slea, final MapleClient c) { final String Secondpw_Client = slea.readMapleAsciiString(); final int Character_ID = slea.readInt(); if (!c.login_Auth(Character_ID) || !c.isLoggedIn() || loginFailCount(c) || c.getSecondPassword() == null) { c.getSession().close(true); return; // Attempting to delete other character } byte state = 0; if (!c.CheckSecondPassword(Secondpw_Client)) { // Wrong Password state = 20; } if (state == 0) { state = (byte) c.deleteCharacter(Character_ID); } c.getSession().write(LoginPacket.deleteCharResponse(Character_ID, state)); } public static void Character_WithoutSecondPassword(final LittleEndianAccessor slea, final MapleClient c, final boolean haspic, final boolean view) { final int charId = slea.readInt(); if (view) { c.setChannel(1); c.setWorld(slea.readInt()); } final String currentpw = c.getSecondPassword(); if (!c.isLoggedIn() || loginFailCount(c) || /*(currentpw != null && (!currentpw.equals("") || haspic)) || */ !c.login_Auth(charId) || ChannelServer.getInstance(c.getChannel()) == null || !WorldConstants.isExists(c.getWorld())) { c.getSession().close(true); return; } //c.updateMacs(slea.readMapleAsciiString()); //slea.readMapleAsciiString(); /*if (slea.available() != 0) { final String setpassword = slea.readMapleAsciiString(); if (setpassword.length() >= 6 && setpassword.length() <= 16) { c.setSecondPassword(setpassword); c.updateSecondPassword(); } else { c.getSession().write(LoginPacket.secondPwError((byte) 0x14)); return; } } else if (haspic) { return; }*/ if (c.getIdleTask() != null) { c.getIdleTask().cancel(true); } final String s = c.getSessionIPAddress(); LoginServer.putLoginAuth(charId, s.substring(s.indexOf('/') + 1, s.length()), c.getTempIP(), c.getChannel()); c.updateLoginState(MapleClient.LOGIN_SERVER_TRANSITION, s); c.getSession().write(CField.getServerIP(c, Integer.parseInt(ChannelServer.getInstance(c.getChannel()).getIP().split(":")[1]), charId)); } public static void Character_WithSecondPassword(final LittleEndianAccessor slea, final MapleClient c, final boolean view) { final String password = slea.readMapleAsciiString(); final int charId = slea.readInt(); if (view) { c.setChannel(1); c.setWorld(slea.readInt()); } if (!c.isLoggedIn() || loginFailCount(c) || c.getSecondPassword() == null || !c.login_Auth(charId) || ChannelServer.getInstance(c.getChannel()) == null || !WorldConstants.isExists(c.getWorld())) { c.getSession().close(true); return; } c.updateMacs(slea.readMapleAsciiString()); if (c.CheckSecondPassword(password) && password.length() >= 6 && password.length() <= 16 || c.isGM()) { if (c.getIdleTask() != null) { c.getIdleTask().cancel(true); } final String s = c.getSessionIPAddress(); LoginServer.putLoginAuth(charId, s.substring(s.indexOf('/') + 1, s.length()), c.getTempIP(), c.getChannel()); c.updateLoginState(MapleClient.LOGIN_SERVER_TRANSITION, s); c.getSession().write(CField.getServerIP(c, Integer.parseInt(ChannelServer.getInstance(c.getChannel()).getIP().split(":")[1]), charId)); } else { c.getSession().write(LoginPacket.secondPwError((byte) 0x14)); } } public static void partTimeJob(final LittleEndianAccessor slea, final MapleClient c) { System.out.println("[Part Time Job] data: " + slea); byte mode = slea.readByte(); //1 = start 2 = end int cid = slea.readInt(); //character id byte job = slea.readByte(); //part time job if (mode == 0) { LoginPacket.partTimeJob(cid, (byte) 0, System.currentTimeMillis()); } else if (mode == 1) { LoginPacket.partTimeJob(cid, job, System.currentTimeMillis()); } } public static void PartJob(LittleEndianAccessor slea, MapleClient c) { if (c.getPlayer() != null || !c.isLoggedIn()) { c.getSession().close(true); return; } final byte mode = slea.readByte(); final int cid = slea.readInt(); if (mode == 1) { // 開始打工 final PartTimeJob partTime = MapleCharacter.getPartTime(cid); final byte job = slea.readByte(); if (/*chr.getLevel() < 30 || */job < 0 || job > 5 || partTime.getReward() > 0 || (partTime.getJob() > 0 && partTime.getJob() <= 5)) { c.getSession().close(true); return; } partTime.setTime(System.currentTimeMillis()); partTime.setJob(job); c.getSession().write(LoginPacket.updatePartTimeJob(partTime)); MapleCharacter.removePartTime(cid); MapleCharacter.addPartTime(partTime); } else if (mode == 2) { // 結束打工 final PartTimeJob partTime = MapleCharacter.getPartTime(cid); if (/*chr.getLevel() < 30 || */partTime.getReward() > 0 || partTime.getJob() < 0 || partTime.getJob() > 5) { c.getSession().close(true); return; } final long distance = (System.currentTimeMillis() - partTime.getTime()) / (60 * 60 * 1000L); if (distance > 1) { partTime.setReward((int) (((partTime.getJob() + 1) * 1000L) + distance)); } else { partTime.setJob((byte) 0); partTime.setReward(0); } partTime.setTime(System.currentTimeMillis()); MapleCharacter.removePartTime(cid); MapleCharacter.addPartTime(partTime); c.getSession().write(LoginPacket.updatePartTimeJob(partTime)); } } public static void SetGender(LittleEndianAccessor slea, MapleClient c) { String name = slea.readMapleAsciiString(); String secondPassword = slea.readMapleAsciiString(); byte gender = slea.readByte(); if (!c.getAccountName().equals(name) || c.getSecondPassword() != null || gender < 0 || gender > 1) { c.getSession().write(LoginPacket.genderChanged(false)); return; } c.clearInformation(); if (secondPassword.length() >= 5) { Connection con = DatabaseConnection.getConnection(); PreparedStatement ps; try { ps = con.prepareStatement("UPDATE accounts SET gender = ?, 2ndpassword = ? WHERE name = ?"); ps.setInt(1, gender); ps.setString(2, LoginCrypto.hexSha1(secondPassword)); ps.setString(3, name); ps.execute(); ps.close(); } catch (SQLException ex) { } c.getSession().write(LoginPacket.genderChanged(true)); } else { c.getSession().write(LoginPacket.genderChanged(false)); } } }