/* This file is part of the OdinMS Maple Story Server Copyright (C) 2008 ~ 2010 Patrick Huy <patrick.huy@frz.cc> Matthias Butz <matze@odinms.de> Jan Christian Meyer <vimes@odinms.de> This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation. You may not use, modify or distribute this program under any other version of the GNU Affero General Public License. This program 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package handling.channel.handler; import clientside.MapleCharacter; import clientside.MapleClient; import clientside.Skill; import clientside.SkillFactory; import handling.world.World; import handling.world.guild.MapleGuild; import handling.world.guild.MapleGuildResponse; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import server.MapleStatEffect; import tools.Pair; import tools.data.LittleEndianAccessor; import tools.packet.CField; import tools.packet.CWvsContext.GuildPacket; public class GuildHandler { public static void DenyGuildRequest(final String from, final MapleClient c) { final MapleCharacter cfrom = c.getChannelServer().getPlayerStorage().getCharacterByName(from); if (cfrom != null && invited.remove(c.getPlayer().getName().toLowerCase()) != null) { cfrom.getClient().getSession().write(GuildPacket.denyGuildInvitation(c.getPlayer().getName())); } } private static boolean isGuildNameAcceptable(final String name) { if (name.length() < 3 || name.length() > 12) { return false; } for (int i = 0; i < name.length(); i++) { if (!Character.isLowerCase(name.charAt(i)) && !Character.isUpperCase(name.charAt(i))) { return false; } } return true; } private static void respawnPlayer(final MapleCharacter mc) { if (mc.getMap() == null) { return; } mc.getMap().broadcastMessage(CField.loadGuildName(mc)); mc.getMap().broadcastMessage(CField.loadGuildIcon(mc)); } private static final Map<String, Pair<Integer, Long>> invited = new HashMap<>(); private static long nextPruneTime = System.currentTimeMillis() + 5 * 60 * 1000; public static void Guild(final LittleEndianAccessor slea, final MapleClient c) { final long currentTime = System.currentTimeMillis(); if (currentTime >= nextPruneTime) { Iterator<Entry<String, Pair<Integer, Long>>> itr = invited.entrySet().iterator(); Entry<String, Pair<Integer, Long>> inv; while (itr.hasNext()) { inv = itr.next(); if (currentTime >= inv.getValue().right) { itr.remove(); } } nextPruneTime += 5 * 60 * 1000; } byte bla = slea.readByte(); switch (bla) { //AFTERSHOCK: most are +1 case 0x02: // Create guild if (c.getPlayer().getGuildId() > 0 || c.getPlayer().getMapId() != 200000301) { c.getPlayer().dropMessage(1, "You cannot create a new Guild while in one."); return; } else if (c.getPlayer().getMeso() < 500000) { c.getPlayer().dropMessage(1, "You do not have enough mesos to create a Guild."); return; } final String guildName = slea.readMapleAsciiString(); if (!isGuildNameAcceptable(guildName)) { c.getPlayer().dropMessage(1, "The Guild name you have chosen is not accepted."); return; } int guildId = World.Guild.createGuild(c.getPlayer().getId(), guildName); if (guildId == 0) { c.getPlayer().dropMessage(1, "Please try again."); return; } c.getPlayer().gainMeso(-500000, true, true); c.getPlayer().setGuildId(guildId); c.getPlayer().setGuildRank((byte) 1); c.getPlayer().saveGuildStatus(); World.Guild.setGuildMemberOnline(c.getPlayer().getMGC(), true, c.getChannel()); //c.getSession().write(GuildPacket.showGuildInfo(c.getPlayer())); c.getSession().write(GuildPacket.newGuildInfo(c.getPlayer())); World.Guild.gainGP(c.getPlayer().getGuildId(), 500, c.getPlayer().getId()); //c.getPlayer().dropMessage(1, "You have successfully created a Guild."); //respawnPlayer(c.getPlayer()); break; case 0x05: // invitation if (c.getPlayer().getGuildId() <= 0 || c.getPlayer().getGuildRank() > 2) { // 1 == guild master, 2 == jr return; } String name = slea.readMapleAsciiString().toLowerCase(); if (invited.containsKey(name)) { c.getPlayer().dropMessage(5, "The player is currently handling an invitation."); return; } final MapleGuildResponse mgr = MapleGuild.sendInvite(c, name); if (mgr != null) { c.getSession().write(mgr.getPacket()); } else { invited.put(name, new Pair<>(c.getPlayer().getGuildId(), currentTime + (20 * 60000))); //20 mins expire } break; case 0x06: // accepted guild invitation if (c.getPlayer().getGuildId() > 0) { return; } guildId = slea.readInt(); int cid = slea.readInt(); if (cid != c.getPlayer().getId()) { return; } name = c.getPlayer().getName().toLowerCase(); Pair<Integer, Long> gid = invited.remove(name); if (gid != null && guildId == gid.left) { c.getPlayer().setGuildId(guildId); c.getPlayer().setGuildRank((byte) 5); int s = World.Guild.addGuildMember(c.getPlayer().getMGC()); if (s == 0) { c.getPlayer().dropMessage(1, "The Guild you are trying to join is already full."); c.getPlayer().setGuildId(0); return; } c.getSession().write(GuildPacket.showGuildInfo(c.getPlayer())); final MapleGuild gs = World.Guild.getGuild(guildId); for (byte[] pack : World.Alliance.getAllianceInfo(gs.getAllianceId(), true)) { if (pack != null) { c.getSession().write(pack); } } c.getPlayer().saveGuildStatus(); respawnPlayer(c.getPlayer()); } break; case 0x07: // leaving cid = slea.readInt(); name = slea.readMapleAsciiString(); if (cid != c.getPlayer().getId() || !name.equals(c.getPlayer().getName()) || c.getPlayer().getGuildId() <= 0) { return; } World.Guild.leaveGuild(c.getPlayer().getMGC()); c.getSession().write(GuildPacket.showGuildInfo(null)); break; case 0x08: // Expel cid = slea.readInt(); name = slea.readMapleAsciiString(); if (c.getPlayer().getGuildRank() > 2 || c.getPlayer().getGuildId() <= 0) { return; } World.Guild.expelMember(c.getPlayer().getMGC(), name, cid); break; case 0x0e: // Guild rank titles change if (c.getPlayer().getGuildId() <= 0 || c.getPlayer().getGuildRank() != 1) { return; } String ranks[] = new String[5]; for (int i = 0; i < 5; i++) { ranks[i] = slea.readMapleAsciiString(); } World.Guild.changeRankTitle(c.getPlayer().getGuildId(), ranks); break; case 0x0f: // Rank change cid = slea.readInt(); byte newRank = slea.readByte(); if ((newRank <= 1 || newRank > 5) || c.getPlayer().getGuildRank() > 2 || (newRank <= 2 && c.getPlayer().getGuildRank() != 1) || c.getPlayer().getGuildId() <= 0) { return; } World.Guild.changeRank(c.getPlayer().getGuildId(), cid, newRank); break; case 0x10: // guild emblem change if (c.getPlayer().getGuildId() <= 0 || c.getPlayer().getGuildRank() != 1 || c.getPlayer().getMapId() != 200000301) { return; } if (c.getPlayer().getMeso() < 1500000) { c.getPlayer().dropMessage(1, "You do not have enough mesos to create an emblem."); return; } final short bg = slea.readShort(); final byte bgcolor = slea.readByte(); final short logo = slea.readShort(); final byte logocolor = slea.readByte(); World.Guild.setGuildEmblem(c.getPlayer().getGuildId(), bg, bgcolor, logo, logocolor); c.getPlayer().gainMeso(-1500000, true, true); respawnPlayer(c.getPlayer()); break; case 0x11: // guild notice change final String notice = slea.readMapleAsciiString(); if (notice.length() > 100 || c.getPlayer().getGuildId() <= 0 || c.getPlayer().getGuildRank() > 2) { return; } World.Guild.setGuildNotice(c.getPlayer().getGuildId(), notice); break; case 0x1d: //guild skill purchase Skill skilli = SkillFactory.getSkill(slea.readInt()); if (c.getPlayer().getGuildId() <= 0 || skilli == null || skilli.getId() < 91000000) { return; } int eff = World.Guild.getSkillLevel(c.getPlayer().getGuildId(), skilli.getId()) + 1; if (eff > skilli.getMaxLevel()) { return; } final MapleStatEffect skillid = skilli.getEffect(eff); if (skillid.getReqGuildLevel() <= 0 || c.getPlayer().getMeso() < skillid.getPrice()) { return; } if (World.Guild.purchaseSkill(c.getPlayer().getGuildId(), skillid.getSourceId(), c.getPlayer().getName(), c.getPlayer().getId())) { c.getPlayer().gainMeso(-skillid.getPrice(), true); } break; case 0x1e: //guild skill activation skilli = SkillFactory.getSkill(slea.readInt()); if (c.getPlayer().getGuildId() <= 0 || skilli == null) { return; } eff = World.Guild.getSkillLevel(c.getPlayer().getGuildId(), skilli.getId()); if (eff <= 0) { return; } final MapleStatEffect skillii = skilli.getEffect(eff); if (skillii.getReqGuildLevel() < 0 || c.getPlayer().getMeso() < skillii.getExtendPrice()) { return; } if (World.Guild.activateSkill(c.getPlayer().getGuildId(), skillii.getSourceId(), c.getPlayer().getName())) { c.getPlayer().gainMeso(-skillii.getExtendPrice(), true); } break; case 0x1f: //guild leader change cid = slea.readInt(); if (c.getPlayer().getGuildId() <= 0 || c.getPlayer().getGuildRank() > 1) { return; } World.Guild.setGuildLeader(c.getPlayer().getGuildId(), cid); break; } } }