Source for my MapleSolaxiaV2 (v83 MapleStory).
This commit is contained in:
ronancpl
2015-11-02 23:17:21 -02:00
parent 324982e94f
commit 972517e7b2
1675 changed files with 261831 additions and 0 deletions

145
src/client/BuddyList.java Normal file
View File

@@ -0,0 +1,145 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Deque;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Map;
import tools.DatabaseConnection;
import tools.MaplePacketCreator;
public class BuddyList {
public enum BuddyOperation {
ADDED, DELETED
}
public enum BuddyAddResult {
BUDDYLIST_FULL, ALREADY_ON_LIST, OK
}
private Map<Integer, BuddylistEntry> buddies = new LinkedHashMap<>();
private int capacity;
private Deque<CharacterNameAndId> pendingRequests = new LinkedList<>();
public BuddyList(int capacity) {
this.capacity = capacity;
}
public boolean contains(int characterId) {
return buddies.containsKey(Integer.valueOf(characterId));
}
public boolean containsVisible(int characterId) {
BuddylistEntry ble = buddies.get(characterId);
if (ble == null) {
return false;
}
return ble.isVisible();
}
public int getCapacity() {
return capacity;
}
public void setCapacity(int capacity) {
this.capacity = capacity;
}
public BuddylistEntry get(int characterId) {
return buddies.get(Integer.valueOf(characterId));
}
public BuddylistEntry get(String characterName) {
String lowerCaseName = characterName.toLowerCase();
for (BuddylistEntry ble : buddies.values()) {
if (ble.getName().toLowerCase().equals(lowerCaseName)) {
return ble;
}
}
return null;
}
public void put(BuddylistEntry entry) {
buddies.put(Integer.valueOf(entry.getCharacterId()), entry);
}
public void remove(int characterId) {
buddies.remove(Integer.valueOf(characterId));
}
public Collection<BuddylistEntry> getBuddies() {
return buddies.values();
}
public boolean isFull() {
return buddies.size() >= capacity;
}
public int[] getBuddyIds() {
int buddyIds[] = new int[buddies.size()];
int i = 0;
for (BuddylistEntry ble : buddies.values()) {
buddyIds[i++] = ble.getCharacterId();
}
return buddyIds;
}
public void loadFromDb(int characterId) {
try {
PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("SELECT b.buddyid, b.pending, b.group, c.name as buddyname FROM buddies as b, characters as c WHERE c.id = b.buddyid AND b.characterid = ?");
ps.setInt(1, characterId);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
if (rs.getInt("pending") == 1) {
pendingRequests.push(new CharacterNameAndId(rs.getInt("buddyid"), rs.getString("buddyname")));
} else {
put(new BuddylistEntry(rs.getString("buddyname"), rs.getString("group"), rs.getInt("buddyid"), (byte) -1, true));
}
}
rs.close();
ps.close();
ps = DatabaseConnection.getConnection().prepareStatement("DELETE FROM buddies WHERE pending = 1 AND characterid = ?");
ps.setInt(1, characterId);
ps.executeUpdate();
ps.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
public CharacterNameAndId pollPendingRequest() {
return pendingRequests.pollLast();
}
public void addBuddyRequest(MapleClient c, int cidFrom, String nameFrom, int channelFrom) {
put(new BuddylistEntry(nameFrom, "Default Group", cidFrom, channelFrom, false));
if (pendingRequests.isEmpty()) {
c.announce(MaplePacketCreator.requestBuddylistAdd(cidFrom, c.getPlayer().getId(), nameFrom));
} else {
pendingRequests.push(new CharacterNameAndId(cidFrom, nameFrom));
}
}
}

View File

@@ -0,0 +1,110 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client;
public class BuddylistEntry {
private String name;
private String group;
private int cid;
private int channel;
private boolean visible;
/**
*
* @param name
* @param characterId
* @param channel should be -1 if the buddy is offline
* @param visible
*/
public BuddylistEntry(String name, String group, int characterId, int channel, boolean visible) {
this.name = name;
this.group = group;
this.cid = characterId;
this.channel = channel;
this.visible = visible;
}
/**
* @return the channel the character is on. If the character is offline returns -1.
*/
public int getChannel() {
return channel;
}
public void setChannel(int channel) {
this.channel = channel;
}
public boolean isOnline() {
return channel >= 0;
}
public String getName() {
return name;
}
public String getGroup() {
return group;
}
public int getCharacterId() {
return cid;
}
public void setVisible(boolean visible) {
this.visible = visible;
}
public boolean isVisible() {
return visible;
}
public void changeGroup(String group) {
this.group = group;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + cid;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final BuddylistEntry other = (BuddylistEntry) obj;
if (cid != other.cid) {
return false;
}
return true;
}
}

View File

@@ -0,0 +1,41 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client;
public class CharacterNameAndId {
private int id;
private String name;
public CharacterNameAndId(int id, String name) {
super();
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
}

View File

@@ -0,0 +1,34 @@
/*
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 client;
/**
*
* @author anybody can do this
*/
public class DiseaseValueHolder {
public long startTime, length;
public DiseaseValueHolder(long start, long length) {
this.startTime = start;
this.length = length;
}
}

View File

@@ -0,0 +1,140 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client;
public enum MapleBuffStat {
//SLOW(0x1),
MORPH(0x2),
RECOVERY(0x4),
MAPLE_WARRIOR(0x8),
STANCE(0x10),
SHARP_EYES(0x20),
MANA_REFLECTION(0x40),
//ALWAYS_RIGHT(0X80),
//------ bgn EDITED SLOT (was unused before) --------
MAP_PROTECTION(0x100000000000000L),
//------ end EDITED SLOT ----------------------------
SHADOW_CLAW(0x100),
INFINITY(0x200),
HOLY_SHIELD(0x400),
HAMSTRING(0x800),
BLIND(0x1000),
CONCENTRATE(0x2000),
//4000
ECHO_OF_HERO(0x8000),
//10000
GHOST_MORPH(0x20000),
AURA(0x40000),
CONFUSE(0x80000),
//100000
//200000
//400000
//800000
//1000000
//2000000
//4000000
BERSERK_FURY(0x8000000),
DIVINE_BODY(0x10000000),
SPARK(0x20000000L),
//40000000
FINALATTACK(0x80000000L),
BATTLESHIP(0xA00000040L), // weird one
WATK(0x100000000L),
WDEF(0x200000000L),
MATK(0x400000000L),
MDEF(0x800000000L),
ACC(0x1000000000L),
AVOID(0x2000000000L),
HANDS(0x4000000000L),
SHOWDASH(0x4000000000L),
SPEED(0x8000000000L),
JUMP(0x10000000000L),
MAGIC_GUARD(0x20000000000L),
DARKSIGHT(0x40000000000L),
BOOSTER(0x80000000000L),
POWERGUARD(0x100000000000L),
HYPERBODYHP(0x200000000000L),
HYPERBODYMP(0x400000000000L),
INVINCIBLE(0x800000000000L),
SOULARROW(0x1000000000000L),
STUN(0x2000000000000L),
POISON(0x4000000000000L),
SEAL(0x8000000000000L),
DARKNESS(0x10000000000000L),
COMBO(0x20000000000000L),
SUMMON(0x20000000000000L),
WK_CHARGE(0x40000000000000L),
DRAGONBLOOD(0x80000000000000L),
HOLY_SYMBOL(0x100000000000000L),
MESOUP(0x200000000000000L),
SHADOWPARTNER(0x400000000000000L),
PICKPOCKET(0x800000000000000L),
PUPPET(0x800000000000000L),
MESOGUARD(0x1000000000000000L),
//0x2000000000000000L
WEAKEN(0x4000000000000000L),
//THAT GAP
//all incorrect buffstats
SLOW(0x200000000L, true),
ELEMENTAL_RESET(0x200000000L, true),
MAGIC_SHIELD(0x400000000L, true),
MAGIC_RESISTANCE(0x800000000L, true),
// needs Soul Stone
//end incorrect buffstats
ARAN_COMBO(0x1000000000L, true),
COMBO_DRAIN(0x2000000000L, true),
COMBO_BARRIER(0x4000000000L, true),
BODY_PRESSURE(0x8000000000L, true),
SMART_KNOCKBACK(0x10000000000L, true),
PYRAMID_PQ(0x20000000000L, true),
ENERGY_CHARGE(0x4000000000000L, true),
DASH2(0x8000000000000L, true), // correct (speed)
DASH(0x10000000000000L, true), // correct (jump)
MONSTER_RIDING(0x20000000000000L, true),
SPEED_INFUSION(0x40000000000000L, true),
HOMING_BEACON(0x80000000000000L, true);
private final long i;
private final boolean isFirst;
private MapleBuffStat(long i, boolean isFirst) {
this.i = i;
this.isFirst = isFirst;
}
private MapleBuffStat(long i) {
this.i = i;
this.isFirst = false;
}
public long getValue() {
return i;
}
public boolean isFirst() {
return isFirst;
}
}

File diff suppressed because it is too large Load Diff

1260
src/client/MapleClient.java Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,58 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client;
public enum MapleDisease {
NULL(0x0),
SLOW(0x1),
SEDUCE(0x80),
FISHABLE(0x100),
CONFUSE(0x80000),
STUN(0x2000000000000L),
POISON(0x4000000000000L),
SEAL(0x8000000000000L),
DARKNESS(0x10000000000000L),
WEAKEN(0x4000000000000000L),
CURSE(0x8000000000000000L);
private long i;
private boolean first;
private MapleDisease(long i) {
this.i = i;
this.first = false;
}
private MapleDisease(long i, boolean first) {
this.i = i;
this.first = first;
}
public long getValue() {
return i;
}
public boolean isFirst() {
return first;
}
}

View File

@@ -0,0 +1,88 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import tools.DatabaseConnection;
/**
*
* @author Jay Estrella :3 (Mr.Trash)
*/
public class MapleFamily {
private static int id;
private static Map<Integer, MapleFamilyEntry> members = new HashMap<Integer, MapleFamilyEntry>();
public MapleFamily(int cid) {
try {
PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("SELECT familyid FROM family_character WHERE cid = ?");
ps.setInt(1, cid);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
id = rs.getInt("familyid");
}
ps.close();
rs.close();
getMapleFamily();
} catch (SQLException ex) {
}
}
private static void getMapleFamily() {
try {
PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("SELECT * FROM family_character WHERE familyid = ?");
ps.setInt(1, id);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
MapleFamilyEntry ret = new MapleFamilyEntry();
ret.setFamilyId(id);
ret.setRank(rs.getInt("rank"));
ret.setReputation(rs.getInt("reputation"));
ret.setTotalJuniors(rs.getInt("totaljuniors"));
ret.setFamilyName(rs.getString("name"));
ret.setJuniors(rs.getInt("juniorsadded"));
ret.setTodaysRep(rs.getInt("todaysrep"));
int cid = rs.getInt("cid");
ret.setChrId(cid);
members.put(cid, ret);
}
rs.close();
ps.close();
} catch (SQLException sqle) {
}
}
public MapleFamilyEntry getMember(int cid) {
if (members.containsKey(cid)){
return members.get(cid);
}
return null;
}
public Map<Integer, MapleFamilyEntry> getMembers() {
return members;
}
}

View File

@@ -0,0 +1,105 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client;
public class MapleFamilyEntry {
private int familyId;
private int rank, reputation, totalReputation, todaysRep, totalJuniors, juniors, chrid;
private String familyName;
public int getId() {
return familyId;
}
public void setFamilyId(int familyId) {
this.familyId = familyId;
}
public int getRank() {
return rank;
}
public void setRank(int rank) {
this.rank = rank;
}
public int getChrId() {
return chrid;
}
public void setChrId(int chrid) {
this.chrid = chrid;
}
public int getReputation() {
return reputation;
}
public int getTodaysRep() {
return todaysRep;
}
public void setReputation(int reputation) {
this.reputation = reputation;
}
public void setTodaysRep(int today) {
this.todaysRep = today;
}
public void gainReputation(int gain) {
this.reputation += gain;
this.totalReputation += gain;
}
public int getTotalJuniors() {
return totalJuniors;
}
public void setTotalJuniors(int totalJuniors) {
this.totalJuniors = totalJuniors;
}
public int getJuniors() {
return juniors;
}
public void setJuniors(int juniors) {
this.juniors = juniors;
}
public void setFamilyName(String familyName) {
this.familyName = familyName;
}
public String getFamilyName() {
return familyName;
}
public int getTotalReputation() {
return totalReputation;
}
public void setTotalReputation(int totalReputation) {
this.totalReputation = totalReputation;
}
}

121
src/client/MapleJob.java Normal file
View File

@@ -0,0 +1,121 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client;
public enum MapleJob {
BEGINNER(0),
WARRIOR(100),
FIGHTER(110), CRUSADER(111), HERO(112),
PAGE(120), WHITEKNIGHT(121), PALADIN(122),
SPEARMAN(130), DRAGONKNIGHT(131), DARKKNIGHT(132),
MAGICIAN(200),
FP_WIZARD(210), FP_MAGE(211), FP_ARCHMAGE(212),
IL_WIZARD(220), IL_MAGE(221), IL_ARCHMAGE(222),
CLERIC(230), PRIEST(231), BISHOP(232),
BOWMAN(300),
HUNTER(310), RANGER(311), BOWMASTER(312),
CROSSBOWMAN(320), SNIPER(321), MARKSMAN(322),
THIEF(400),
ASSASSIN(410), HERMIT(411), NIGHTLORD(412),
BANDIT(420), CHIEFBANDIT(421), SHADOWER(422),
PIRATE(500),
BRAWLER(510), MARAUDER(511), BUCCANEER(512),
GUNSLINGER(520), OUTLAW(521), CORSAIR(522),
MAPLELEAF_BRIGADIER(800),
GM(900), SUPERGM(910),
NOBLESSE(1000),
DAWNWARRIOR1(1100), DAWNWARRIOR2(1110), DAWNWARRIOR3(1111), DAWNWARRIOR4(1112),
BLAZEWIZARD1(1200), BLAZEWIZARD2(1210), BLAZEWIZARD3(1211), BLAZEWIZARD4(1212),
WINDARCHER1(1300), WINDARCHER2(1310), WINDARCHER3(1311), WINDARCHER4(1312),
NIGHTWALKER1(1400), NIGHTWALKER2(1410), NIGHTWALKER3(1411), NIGHTWALKER4(1412),
THUNDERBREAKER1(1500), THUNDERBREAKER2(1510), THUNDERBREAKER3(1511), THUNDERBREAKER4(1512),
LEGEND(2000), EVAN(2001),
ARAN1(2100),ARAN2(2110), ARAN3(2111), ARAN4(2112),
EVAN1(2200), EVAN2(2210), EVAN3(2211), EVAN4(2212), EVAN5(2213), EVAN6(2214),
EVAN7(2215), EVAN8(2216), EVAN9(2217), EVAN10(2218);
final int jobid;
private MapleJob(int id) {
jobid = id;
}
public int getId() {
return jobid;
}
public static MapleJob getById(int id) {
for (MapleJob l : MapleJob.values()) {
if (l.getId() == id) {
return l;
}
}
return null;
}
public static MapleJob getBy5ByteEncoding(int encoded) {
switch (encoded) {
case 2:
return WARRIOR;
case 4:
return MAGICIAN;
case 8:
return BOWMAN;
case 16:
return THIEF;
case 32:
return PIRATE;
case 1024:
return NOBLESSE;
case 2048:
return DAWNWARRIOR1;
case 4096:
return BLAZEWIZARD1;
case 8192:
return WINDARCHER1;
case 16384:
return NIGHTWALKER1;
case 32768:
return THUNDERBREAKER1;
default:
return BEGINNER;
}
}
public boolean isBeginner(MapleJob beginners) {
return MAGICIAN == beginners || WARRIOR == beginners || THIEF == beginners || PIRATE == beginners || BOWMAN == beginners || ARAN1 == beginners || THUNDERBREAKER1 == beginners
|| DAWNWARRIOR1 == beginners || NIGHTWALKER1 == beginners || BLAZEWIZARD1 == beginners;
}
public boolean isA(MapleJob basejob) {
return getId() >= basejob.getId() && getId() / 100 == basejob.getId() / 100;
}
}

View File

@@ -0,0 +1,39 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client;
public class MapleKeyBinding {
private int type, action;
public MapleKeyBinding(int type, int action) {
this.type = type;
this.action = action;
}
public int getType() {
return type;
}
public int getAction() {
return action;
}
}

154
src/client/MapleMount.java Normal file
View File

@@ -0,0 +1,154 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client;
import java.util.concurrent.ScheduledFuture;
import server.TimerManager;
import tools.MaplePacketCreator;
/**
* @author PurpleMadness Patrick :O
*/
public class MapleMount {
private int itemid;
private int skillid;
private int tiredness;
private int exp;
private int level;
private ScheduledFuture<?> tirednessSchedule;
private MapleCharacter owner;
private boolean active;
public MapleMount(MapleCharacter owner, int id, int skillid) {
this.itemid = id;
this.skillid = skillid;
this.tiredness = 0;
this.level = 1;
this.exp = 0;
this.owner = owner;
active = true;
}
public int getItemId() {
return itemid;
}
public int getSkillId() {
return skillid;
}
/**
* 1902000 - Hog
* 1902001 - Silver Mane
* 1902002 - Red Draco
* 1902005 - Mimiana
* 1902006 - Mimio
* 1902007 - Shinjou
* 1902008 - Frog
* 1902009 - Ostrich
* 1902010 - Frog
* 1902011 - Turtle
* 1902012 - Yeti
* @return the id
*/
public int getId() {
if (this.itemid < 1903000) {
return itemid - 1901999;
}
return 5;
}
public int getTiredness() {
return tiredness;
}
public int getExp() {
return exp;
}
public int getLevel() {
return level;
}
public void setTiredness(int newtiredness) {
this.tiredness = newtiredness;
if (tiredness < 0) {
tiredness = 0;
}
}
private void increaseTiredness() {
if(owner != null) {
this.tiredness++;
owner.getMap().broadcastMessage(MaplePacketCreator.updateMount(owner.getId(), this, false));
if (tiredness > 99) {
this.tiredness = 95;
owner.dispelSkill(owner.getJobType() * 10000000 + 1004);
}
} else {
if(this.tirednessSchedule != null) {
this.tirednessSchedule.cancel(false);
}
}
}
public void setExp(int newexp) {
this.exp = newexp;
}
public void setLevel(int newlevel) {
this.level = newlevel;
}
public void setItemId(int newitemid) {
this.itemid = newitemid;
}
public void startSchedule() {
this.tirednessSchedule = TimerManager.getInstance().register(new Runnable() {
@Override
public void run() {
increaseTiredness();
}
}, 60000, 60000);
}
public void cancelSchedule() {
if (this.tirednessSchedule != null) {
this.tirednessSchedule.cancel(false);
}
}
public void setActive(boolean set) {
this.active = set;
}
public boolean isActive() {
return active;
}
public void empty() {
cancelSchedule();
this.tirednessSchedule = null;
this.owner = null;
}
}

View File

@@ -0,0 +1,205 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import server.quest.MapleQuest;
import tools.StringUtil;
/**
*
* @author Matze
*/
public class MapleQuestStatus {
public enum Status {
UNDEFINED(-1),
NOT_STARTED(0),
STARTED(1),
COMPLETED(2);
final int status;
private Status(int id) {
status = id;
}
public int getId() {
return status;
}
public static Status getById(int id) {
for (Status l : Status.values()) {
if (l.getId() == id) {
return l;
}
}
return null;
}
}
private short questID;
private Status status;
private Map<Integer, String> progress = new LinkedHashMap<Integer, String>();
private List<Integer> medalProgress = new LinkedList<Integer>();
private int npc;
private long completionTime;
private int forfeited = 0;
private String customData;
public MapleQuestStatus(MapleQuest quest, Status status) {
this.questID = quest.getId();
this.setStatus(status);
this.completionTime = System.currentTimeMillis();
if (status == Status.STARTED)
registerMobs();
}
public MapleQuestStatus(MapleQuest quest, Status status, int npc) {
this.questID = quest.getId();
this.setStatus(status);
this.setNpc(npc);
this.completionTime = System.currentTimeMillis();
if (status == Status.STARTED) {
registerMobs();
}
}
public MapleQuest getQuest() {
return MapleQuest.getInstance(questID);
}
public short getQuestID() {
return questID;
}
public Status getStatus() {
return status;
}
public final void setStatus(Status status) {
this.status = status;
}
public int getNpc() {
return npc;
}
public final void setNpc(int npc) {
this.npc = npc;
}
private void registerMobs() {
for (int i : MapleQuest.getInstance(questID).getRelevantMobs()) {
progress.put(i, "000");
}
}
public boolean addMedalMap(int mapid) {
if (medalProgress.contains(mapid)) return false;
medalProgress.add(mapid);
return true;
}
public int getMedalProgress() {
return medalProgress.size();
}
public List<Integer> getMedalMaps() {
return medalProgress;
}
public boolean progress(int id) {
if (progress.get(id) != null) {
int current = Integer.parseInt(progress.get(id));
String str = StringUtil.getLeftPaddedStr(Integer.toString(current + 1), '0', 3);
progress.put(id, str);
return true;
}
return false;
}
public void setProgress(int id, String pr) {
progress.put(id, pr);
}
public boolean madeProgress() {
return progress.size() > 0;
}
public String getProgress(int id) {
if (progress.get(id) == null) return "";
return progress.get(id);
}
public Map<Integer, String> getProgress() {
return Collections.unmodifiableMap(progress);
}
public long getCompletionTime() {
return completionTime;
}
public void setCompletionTime(long completionTime) {
this.completionTime = completionTime;
}
public int getForfeited() {
return forfeited;
}
public String getInfo() {
if(!progress.containsKey(0) && !getMedalMaps().isEmpty()) {
return Integer.toString(getMedalProgress());
}
return getProgress(0);
}
public void setInfo(String newInfo) {
progress.put(0, newInfo);
}
public void setForfeited(int forfeited) {
if (forfeited >= this.forfeited) {
this.forfeited = forfeited;
} else {
throw new IllegalArgumentException("Can't set forfeits to something lower than before.");
}
}
public final void setCustomData(final String customData) {
this.customData = customData;
}
public final String getCustomData() {
return customData;
}
public String getQuestData() {
StringBuilder str = new StringBuilder();
for (String ps : progress.values()) {
str.append(ps);
}
return str.toString();
}
}

172
src/client/MapleRing.java Normal file
View File

@@ -0,0 +1,172 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import tools.DatabaseConnection;
/**
*
* @author Danny
*/
public class MapleRing implements Comparable<MapleRing> {
private int ringId;
private int ringId2;
private int partnerId;
private int itemId;
private String partnerName;
private boolean equipped = false;
public MapleRing(int id, int id2, int partnerId, int itemid, String partnername) {
this.ringId = id;
this.ringId2 = id2;
this.partnerId = partnerId;
this.itemId = itemid;
this.partnerName = partnername;
}
public static MapleRing loadFromDb(int ringId) {
try {
MapleRing ret = null;
Connection con = DatabaseConnection.getConnection(); // Get a connection to the database
PreparedStatement ps = con.prepareStatement("SELECT * FROM rings WHERE id = ?"); // Get ring details..
ps.setInt(1, ringId);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
ret = new MapleRing(ringId, rs.getInt("partnerRingId"), rs.getInt("partnerChrId"), rs.getInt("itemid"), rs.getString("partnerName"));
}
rs.close();
ps.close();
return ret;
} catch (SQLException ex) {
ex.printStackTrace();
return null;
}
}
public static int createRing(int itemid, final MapleCharacter partner1, final MapleCharacter partner2) {
try {
if (partner1 == null) {
return -2;
} else if (partner2 == null) {
return -1;
}
int[] ringID = new int[2];
Connection con = DatabaseConnection.getConnection();
PreparedStatement ps = con.prepareStatement("INSERT INTO rings (itemid, partnerChrId, partnername) VALUES (?, ?, ?)", Statement.RETURN_GENERATED_KEYS);
ps.setInt(1, itemid);
ps.setInt(2, partner2.getId());
ps.setString(3, partner2.getName());
ps.executeUpdate();
ResultSet rs = ps.getGeneratedKeys();
rs.next();
ringID[0] = rs.getInt(1); // ID.
rs.close();
ps.close();
ps = con.prepareStatement("INSERT INTO rings (itemid, partnerRingId, partnerChrId, partnername) VALUES (?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS);
ps.setInt(1, itemid);
ps.setInt(2, ringID[0]);
ps.setInt(3, partner1.getId());
ps.setString(4, partner1.getName());
ps.executeUpdate();
rs = ps.getGeneratedKeys();
rs.next();
ringID[1] = rs.getInt(1);
rs.close();
ps.close();
ps = con.prepareStatement("UPDATE rings SET partnerRingId = ? WHERE id = ?");
ps.setInt(1, ringID[1]);
ps.setInt(2, ringID[0]);
ps.executeUpdate();
ps.close();
return ringID[0];
} catch (SQLException ex) {
ex.printStackTrace();
return -1;
}
}
public int getRingId() {
return ringId;
}
public int getPartnerRingId() {
return ringId2;
}
public int getPartnerChrId() {
return partnerId;
}
public int getItemId() {
return itemId;
}
public String getPartnerName() {
return partnerName;
}
public boolean equipped() {
return equipped;
}
public void equip() {
this.equipped = true;
}
public void unequip() {
this.equipped = false;
}
@Override
public boolean equals(Object o) {
if (o instanceof MapleRing) {
if (((MapleRing) o).getRingId() == getRingId()) {
return true;
} else {
return false;
}
}
return false;
}
@Override
public int hashCode() {
int hash = 5;
hash = 53 * hash + this.ringId;
return hash;
}
@Override
public int compareTo(MapleRing other) {
if (ringId < other.getRingId()) {
return -1;
} else if (ringId == other.getRingId()) {
return 0;
}
return 1;
}
}

View File

@@ -0,0 +1,44 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client;
public enum MapleSkinColor {
NORMAL(0), DARK(1), BLACK(2), PALE(3), BLUE(4), GREEN(5), WHITE(9), PINK(10);
final int id;
private MapleSkinColor(int id) {
this.id = id;
}
public int getId() {
return id;
}
public static MapleSkinColor getById(int id) {
for (MapleSkinColor l : MapleSkinColor.values()) {
if (l.getId() == id) {
return l;
}
}
return null;
}
}

121
src/client/MapleStat.java Normal file
View File

@@ -0,0 +1,121 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client;
public enum MapleStat {
SKIN(0x1),
FACE(0x2),
HAIR(0x4),
LEVEL(0x10),
JOB(0x20),
STR(0x40),
DEX(0x80),
INT(0x100),
LUK(0x200),
HP(0x400),
MAXHP(0x800),
MP(0x1000),
MAXMP(0x2000),
AVAILABLEAP(0x4000),
AVAILABLESP(0x8000),
EXP(0x10000),
FAME(0x20000),
MESO(0x40000),
PET(0x180008),
GACHAEXP(0x200000);
private final int i;
private MapleStat(int i) {
this.i = i;
}
public int getValue() {
return i;
}
public static MapleStat getByValue(int value) {
for (MapleStat stat : MapleStat.values()) {
if (stat.getValue() == value) {
return stat;
}
}
return null;
}
public static MapleStat getBy5ByteEncoding(int encoded) {
switch (encoded) {
case 64:
return STR;
case 128:
return DEX;
case 256:
return INT;
case 512:
return LUK;
}
return null;
}
public static MapleStat getByString(String type) {
if (type.equals("SKIN")) {
return SKIN;
} else if (type.equals("FACE")) {
return FACE;
} else if (type.equals("HAIR")) {
return HAIR;
} else if (type.equals("LEVEL")) {
return LEVEL;
} else if (type.equals("JOB")) {
return JOB;
} else if (type.equals("STR")) {
return STR;
} else if (type.equals("DEX")) {
return DEX;
} else if (type.equals("INT")) {
return INT;
} else if (type.equals("LUK")) {
return LUK;
} else if (type.equals("HP")) {
return HP;
} else if (type.equals("MAXHP")) {
return MAXHP;
} else if (type.equals("MP")) {
return MP;
} else if (type.equals("MAXMP")) {
return MAXMP;
} else if (type.equals("AVAILABLEAP")) {
return AVAILABLEAP;
} else if (type.equals("AVAILABLESP")) {
return AVAILABLESP;
} else if (type.equals("EXP")) {
return EXP;
} else if (type.equals("FAME")) {
return FAME;
} else if (type.equals("MESO")) {
return MESO;
} else if (type.equals("PET")) {
return PET;
}
return null;
}
}

138
src/client/MonsterBook.java Normal file
View File

@@ -0,0 +1,138 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import tools.DatabaseConnection;
import tools.MaplePacketCreator;
public final class MonsterBook {
private int specialCard;
private int normalCard = 0;
private int bookLevel = 1;
private Map<Integer, Integer> cards = new LinkedHashMap<>();
public void addCard(final MapleClient c, final int cardid) {
c.getPlayer().getMap().broadcastMessage(c.getPlayer(), MaplePacketCreator.showForeginCardEffect(c.getPlayer().getId()), false);
for (Entry<Integer, Integer> all : cards.entrySet()) {
if (all.getKey() == cardid) {
if (all.getValue() > 4) {
c.announce(MaplePacketCreator.addCard(true, cardid, all.getValue()));
} else {
all.setValue(all.getValue() + 1);
c.announce(MaplePacketCreator.addCard(false, cardid, all.getValue()));
c.announce(MaplePacketCreator.showGainCard());
calculateLevel();
}
return;
}
}
cards.put(cardid, 1);
c.announce(MaplePacketCreator.addCard(false, cardid, 1));
c.announce(MaplePacketCreator.showGainCard());
calculateLevel();
c.getPlayer().saveToDB();
}
private void calculateLevel() {
bookLevel = (int) Math.max(1, Math.sqrt((normalCard + specialCard) / 5));
}
public int getBookLevel() {
return bookLevel;
}
public Map<Integer, Integer> getCards() {
return cards;
}
public int getTotalCards() {
return specialCard + normalCard;
}
public int getNormalCard() {
return normalCard;
}
public int getSpecialCard() {
return specialCard;
}
public void loadCards(final int charid) throws SQLException {
try (PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("SELECT cardid, level FROM monsterbook WHERE charid = ? ORDER BY cardid ASC")) {
ps.setInt(1, charid);
try (ResultSet rs = ps.executeQuery()) {
int cardid, level;
while (rs.next()) {
cardid = rs.getInt("cardid");
level = rs.getInt("level");
if (cardid / 1000 >= 2388) {
specialCard++;
} else {
normalCard++;
}
cards.put(cardid, level);
}
}
}
calculateLevel();
}
public void saveCards(final int charid) {
if (cards.isEmpty()) {
return;
}
try {
Connection con = DatabaseConnection.getConnection();
PreparedStatement ps = con.prepareStatement("DELETE FROM monsterbook WHERE charid = ?");
ps.setInt(1, charid);
ps.execute();
ps.close();
boolean first = true;
StringBuilder query = new StringBuilder();
for (Entry<Integer, Integer> all : cards.entrySet()) {
if (first) {
query.append("INSERT INTO monsterbook VALUES (");
first = false;
} else {
query.append(",(");
}
query.append(charid);
query.append(", ");
query.append(all.getKey());
query.append(", ");
query.append(all.getValue());
query.append(")");
}
ps = con.prepareStatement(query.toString());
ps.execute();
ps.close();
} catch (SQLException e) {
}
}
}

79
src/client/Skill.java Normal file
View File

@@ -0,0 +1,79 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client;
import java.util.ArrayList;
import java.util.List;
import server.MapleStatEffect;
import server.life.Element;
public class Skill {
public int id;
public List<MapleStatEffect> effects = new ArrayList<>();
public Element element;
public int animationTime;
public int job;
public boolean action;
public Skill(int id) {
this.id = id;
this.job = id / 10000;
}
public int getId() {
return id;
}
public MapleStatEffect getEffect(int level) {
return effects.get(level - 1);
}
public int getMaxLevel() {
return effects.size();
}
public boolean isFourthJob() {
if (job == 2212) {
return false;
}
if (id == 22170001 || id == 22171003 || id == 22171004 || id == 22181002 || id == 22181003) {
return true;
}
return job % 10 == 2;
}
public Element getElement() {
return element;
}
public int getAnimationTime() {
return animationTime;
}
public boolean isBeginnerSkill() {
return id % 10000000 < 10000;
}
public boolean getAction() {
return action;
}
}

View File

@@ -0,0 +1,402 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client;
import constants.skills.Aran;
import constants.skills.Archer;
import constants.skills.Assassin;
import constants.skills.Bandit;
import constants.skills.Beginner;
import constants.skills.Bishop;
import constants.skills.BlazeWizard;
import constants.skills.Bowmaster;
import constants.skills.Buccaneer;
import constants.skills.ChiefBandit;
import constants.skills.Cleric;
import constants.skills.Corsair;
import constants.skills.Crossbowman;
import constants.skills.Crusader;
import constants.skills.DarkKnight;
import constants.skills.DawnWarrior;
import constants.skills.DragonKnight;
import constants.skills.Evan;
import constants.skills.FPArchMage;
import constants.skills.FPMage;
import constants.skills.FPWizard;
import constants.skills.Fighter;
import constants.skills.GM;
import constants.skills.Gunslinger;
import constants.skills.Hermit;
import constants.skills.Hero;
import constants.skills.Hunter;
import constants.skills.ILArchMage;
import constants.skills.ILMage;
import constants.skills.ILWizard;
import constants.skills.Legend;
import constants.skills.Magician;
import constants.skills.Marauder;
import constants.skills.Marksman;
import constants.skills.NightLord;
import constants.skills.NightWalker;
import constants.skills.Noblesse;
import constants.skills.Page;
import constants.skills.Paladin;
import constants.skills.Pirate;
import constants.skills.Priest;
import constants.skills.Ranger;
import constants.skills.Rogue;
import constants.skills.Shadower;
import constants.skills.Sniper;
import constants.skills.Spearman;
import constants.skills.SuperGM;
import constants.skills.Swordsman;
import constants.skills.ThunderBreaker;
import constants.skills.WhiteKnight;
import constants.skills.WindArcher;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import provider.MapleData;
import provider.MapleDataDirectoryEntry;
import provider.MapleDataFileEntry;
import provider.MapleDataProvider;
import provider.MapleDataProviderFactory;
import provider.MapleDataTool;
import server.MapleStatEffect;
import server.life.Element;
public class SkillFactory {
private static Map<Integer, Skill> skills = new HashMap<>();
private static MapleDataProvider datasource = MapleDataProviderFactory.getDataProvider(MapleDataProviderFactory.fileInWZPath("Skill.wz"));
public static Skill getSkill(int id) {
if (!skills.isEmpty()) {
return skills.get(Integer.valueOf(id));
}
return null;
}
public static void loadAllSkills() {
final MapleDataDirectoryEntry root = datasource.getRoot();
int skillid;
for (MapleDataFileEntry topDir : root.getFiles()) { // Loop thru jobs
if (topDir.getName().length() <= 8) {
for (MapleData data : datasource.getData(topDir.getName())) { // Loop thru each jobs
if (data.getName().equals("skill")) {
for (MapleData data2 : data) { // Loop thru each jobs
if (data2 != null) {
skillid = Integer.parseInt(data2.getName());
skills.put(skillid, loadFromData(skillid, data2));
}
}
}
}
}
}
}
private static Skill loadFromData(int id, MapleData data) {
Skill ret = new Skill(id);
boolean isBuff = false;
int skillType = MapleDataTool.getInt("skillType", data, -1);
String elem = MapleDataTool.getString("elemAttr", data, null);
if (elem != null) {
ret.element = Element.getFromChar(elem.charAt(0));
} else {
ret.element = Element.NEUTRAL;
}
MapleData effect = data.getChildByPath("effect");
if (skillType != -1) {
if (skillType == 2) {
isBuff = true;
}
} else {
MapleData action_ = data.getChildByPath("action");
boolean action = false;
if (action_ == null) {
if (data.getChildByPath("prepare/action") != null) {
action = true;
} else {
switch (id) {
case Gunslinger.INVISIBLE_SHOT:
case Corsair.HYPNOTIZE:
action = true;
break;
}
}
} else {
action = true;
}
ret.action = action;
MapleData hit = data.getChildByPath("hit");
MapleData ball = data.getChildByPath("ball");
isBuff = effect != null && hit == null && ball == null;
isBuff |= action_ != null && MapleDataTool.getString("0", action_, "").equals("alert2");
switch (id) {
case Hero.RUSH:
case Paladin.RUSH:
case DarkKnight.RUSH:
case DragonKnight.SACRIFICE:
case FPMage.EXPLOSION:
case FPMage.POISON_MIST:
case Cleric.HEAL:
case Ranger.MORTAL_BLOW:
case Sniper.MORTAL_BLOW:
case Assassin.DRAIN:
case Hermit.SHADOW_WEB:
case Bandit.STEAL:
case Shadower.SMOKE_SCREEN:
case SuperGM.HEAL_PLUS_DISPEL:
case Hero.MONSTER_MAGNET:
case Paladin.MONSTER_MAGNET:
case DarkKnight.MONSTER_MAGNET:
case Evan.ICE_BREATH:
case Evan.FIRE_BREATH:
case Gunslinger.RECOIL_SHOT:
case Marauder.ENERGY_DRAIN:
case BlazeWizard.FLAME_GEAR:
case NightWalker.SHADOW_WEB:
case NightWalker.POISON_BOMB:
case NightWalker.VAMPIRE:
case ChiefBandit.CHAKRA:
case Evan.RECOVERY_AURA:
isBuff = false;
break;
case Beginner.RECOVERY:
case Beginner.NIMBLE_FEET:
case Beginner.MONSTER_RIDER:
case Beginner.ECHO_OF_HERO:
case Swordsman.IRON_BODY:
case Fighter.AXE_BOOSTER:
case Fighter.POWER_GUARD:
case Fighter.RAGE:
case Fighter.SWORD_BOOSTER:
case Crusader.ARMOR_CRASH:
case Crusader.COMBO:
case Hero.ENRAGE:
case Hero.HEROS_WILL:
case Hero.MAPLE_WARRIOR:
case Hero.STANCE:
case Page.BW_BOOSTER:
case Page.POWER_GUARD:
case Page.SWORD_BOOSTER:
case Page.THREATEN:
case WhiteKnight.BW_FIRE_CHARGE:
case WhiteKnight.BW_ICE_CHARGE:
case WhiteKnight.BW_LIT_CHARGE:
case WhiteKnight.MAGIC_CRASH:
case WhiteKnight.SWORD_FIRE_CHARGE:
case WhiteKnight.SWORD_ICE_CHARGE:
case WhiteKnight.SWORD_LIT_CHARGE:
case Paladin.BW_HOLY_CHARGE:
case Paladin.HEROS_WILL:
case Paladin.MAPLE_WARRIOR:
case Paladin.STANCE:
case Paladin.SWORD_HOLY_CHARGE:
case Spearman.HYPER_BODY:
case Spearman.IRON_WILL:
case Spearman.POLEARM_BOOSTER:
case Spearman.SPEAR_BOOSTER:
case DragonKnight.DRAGON_BLOOD:
case DragonKnight.POWER_CRASH:
case DarkKnight.AURA_OF_BEHOLDER:
case DarkKnight.BEHOLDER:
case DarkKnight.HEROS_WILL:
case DarkKnight.HEX_OF_BEHOLDER:
case DarkKnight.MAPLE_WARRIOR:
case DarkKnight.STANCE:
case Magician.MAGIC_GUARD:
case Magician.MAGIC_ARMOR:
case FPWizard.MEDITATION:
case FPWizard.SLOW:
case FPMage.SEAL:
case FPMage.SPELL_BOOSTER:
case FPArchMage.HEROS_WILL:
case FPArchMage.INFINITY:
case FPArchMage.MANA_REFLECTION:
case FPArchMage.MAPLE_WARRIOR:
case ILWizard.MEDITATION:
case ILMage.SEAL:
case ILWizard.SLOW:
case ILMage.SPELL_BOOSTER:
case ILArchMage.HEROS_WILL:
case ILArchMage.INFINITY:
case ILArchMage.MANA_REFLECTION:
case ILArchMage.MAPLE_WARRIOR:
case Cleric.INVINCIBLE:
case Cleric.BLESS:
case Priest.DISPEL:
case Priest.DOOM:
case Priest.HOLY_SYMBOL:
case Priest.MYSTIC_DOOR:
case Bishop.HEROS_WILL:
case Bishop.HOLY_SHIELD:
case Bishop.INFINITY:
case Bishop.MANA_REFLECTION:
case Bishop.MAPLE_WARRIOR:
case Archer.FOCUS:
case Hunter.BOW_BOOSTER:
case Hunter.SOUL_ARROW:
case Ranger.PUPPET:
case Bowmaster.CONCENTRATE:
case Bowmaster.HEROS_WILL:
case Bowmaster.MAPLE_WARRIOR:
case Bowmaster.SHARP_EYES:
case Crossbowman.CROSSBOW_BOOSTER:
case Crossbowman.SOUL_ARROW:
case Sniper.PUPPET:
case Marksman.BLIND:
case Marksman.HEROS_WILL:
case Marksman.MAPLE_WARRIOR:
case Marksman.SHARP_EYES:
case Rogue.DARK_SIGHT:
case Assassin.CLAW_BOOSTER:
case Assassin.HASTE:
case Hermit.MESO_UP:
case Hermit.SHADOW_PARTNER:
case NightLord.HEROS_WILL:
case NightLord.MAPLE_WARRIOR:
case NightLord.NINJA_AMBUSH:
case NightLord.SHADOW_STARS:
case Bandit.DAGGER_BOOSTER:
case Bandit.HASTE:
case ChiefBandit.MESO_GUARD:
case ChiefBandit.PICKPOCKET:
case Shadower.HEROS_WILL:
case Shadower.MAPLE_WARRIOR:
case Shadower.NINJA_AMBUSH:
case Pirate.DASH:
case Marauder.TRANSFORMATION:
case Buccaneer.SUPER_TRANSFORMATION:
case Corsair.BATTLE_SHIP:
case GM.HIDE:
case SuperGM.HASTE:
case SuperGM.HOLY_SYMBOL:
case SuperGM.BLESS:
case SuperGM.HIDE:
case SuperGM.HYPER_BODY:
case Noblesse.BLESSING_OF_THE_FAIRY:
case Noblesse.ECHO_OF_HERO:
case Noblesse.MONSTER_RIDER:
case Noblesse.NIMBLE_FEET:
case Noblesse.RECOVERY:
case DawnWarrior.COMBO:
case DawnWarrior.FINAL_ATTACK:
case DawnWarrior.IRON_BODY:
case DawnWarrior.RAGE:
case DawnWarrior.SOUL:
case DawnWarrior.SOUL_CHARGE:
case DawnWarrior.SWORD_BOOSTER:
case BlazeWizard.ELEMENTAL_RESET:
case BlazeWizard.FLAME:
case BlazeWizard.IFRIT:
case BlazeWizard.MAGIC_ARMOR:
case BlazeWizard.MAGIC_GUARD:
case BlazeWizard.MEDITATION:
case BlazeWizard.SEAL:
case BlazeWizard.SLOW:
case BlazeWizard.SPELL_BOOSTER:
case WindArcher.BOW_BOOSTER:
case WindArcher.EAGLE_EYE:
case WindArcher.FINAL_ATTACK:
case WindArcher.FOCUS:
case WindArcher.PUPPET:
case WindArcher.SOUL_ARROW:
case WindArcher.STORM:
case WindArcher.WIND_WALK:
case NightWalker.CLAW_BOOSTER:
case NightWalker.DARKNESS:
case NightWalker.DARK_SIGHT:
case NightWalker.HASTE:
case NightWalker.SHADOW_PARTNER:
case ThunderBreaker.DASH:
case ThunderBreaker.ENERGY_CHARGE:
case ThunderBreaker.ENERGY_DRAIN:
case ThunderBreaker.KNUCKLER_BOOSTER:
case ThunderBreaker.LIGHTNING:
case ThunderBreaker.SPARK:
case ThunderBreaker.LIGHTNING_CHARGE:
case ThunderBreaker.SPEED_INFUSION:
case ThunderBreaker.TRANSFORMATION:
case Legend.BLESSING_OF_THE_FAIRY:
case Legend.AGILE_BODY:
case Legend.ECHO_OF_HERO:
case Legend.RECOVERY:
case Legend.MONSTER_RIDER:
case Aran.MAPLE_WARRIOR:
case Aran.HEROS_WILL:
case Aran.POLEARM_BOOSTER:
case Aran.COMBO_DRAIN:
case Aran.SNOW_CHARGE:
case Aran.BODY_PRESSURE:
case Aran.SMART_KNOCKBACK:
case Aran.COMBO_BARRIER:
case Aran.COMBO_ABILITY:
case Evan.BLESSING_OF_THE_FAIRY:
case Evan.RECOVERY:
case Evan.NIMBLE_FEET:
case Evan.HEROS_WILL:
case Evan.ECHO_OF_HERO:
case Evan.MAGIC_BOOSTER:
case Evan.MAGIC_GUARD:
case Evan.ELEMENTAL_RESET:
case Evan.MAPLE_WARRIOR:
case Evan.MAGIC_RESISTANCE:
case Evan.MAGIC_SHIELD:
case Evan.SLOW:
isBuff = true;
break;
}
}
for (MapleData level : data.getChildByPath("level")) {
ret.effects.add(MapleStatEffect.loadSkillEffectFromData(level, id, isBuff));
}
ret.animationTime = 0;
if (effect != null) {
for (MapleData effectEntry : effect) {
ret.animationTime += MapleDataTool.getIntConvert("delay", effectEntry, 0);
}
}
return ret;
}
public static String getSkillName(int skillid) {
MapleData data = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/" + "String.wz")).getData("Skill.img");
StringBuilder skill = new StringBuilder();
skill.append(String.valueOf(skillid));
if (skill.length() == 4) {
skill.delete(0, 4);
skill.append("000").append(String.valueOf(skillid));
}
if (data.getChildByPath(skill.toString()) != null) {
for (MapleData skilldata : data.getChildByPath(skill.toString()).getChildren()) {
if (skilldata.getName().equals("name"))
return MapleDataTool.getString(skilldata, null);
}
}
return null;
}
}

View File

@@ -0,0 +1,64 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client;
public class SkillMacro {
private int skill1;
private int skill2;
private int skill3;
private String name;
private int shout;
private int position;
public SkillMacro(int skill1, int skill2, int skill3, String name, int shout, int position) {
this.skill1 = skill1;
this.skill2 = skill2;
this.skill3 = skill3;
this.name = name;
this.shout = shout;
this.position = position;
}
public int getSkill1() {
return skill1;
}
public int getSkill2() {
return skill2;
}
public int getSkill3() {
return skill3;
}
public String getName() {
return name;
}
public int getShout() {
return shout;
}
public int getPosition() {
return position;
}
}

View File

@@ -0,0 +1,104 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client.autoban;
import client.MapleCharacter;
import constants.ServerConstants;
import net.server.Server;
import tools.FilePrinter;
import tools.MapleLogger;
import tools.MaplePacketCreator;
/**
*
* @author kevintjuh93
*/
public enum AutobanFactory {
MOB_COUNT,
GENERAL,
FIX_DAMAGE,
DAMAGE_HACK(15, 60 * 1000),
DISTANCE_HACK(10, 120 * 1000),
PORTAL_DISTANCE(5, 30000),
PACKET_EDIT,
ACC_HACK,
CREATION_GENERATOR,
HIGH_HP_HEALING,
FAST_HP_HEALING(15),
FAST_MP_HEALING(20, 30000),
GACHA_EXP,
TUBI(20, 15000),
SHORT_ITEM_VAC,
ITEM_VAC,
FAST_ITEM_PICKUP(5, 30000),
FAST_ATTACK(10, 30000),
MPCON(25, 30000);
private int points;
private long expiretime;
private AutobanFactory() {
this(1, -1);
}
private AutobanFactory(int points) {
this.points = points;
this.expiretime = -1;
}
private AutobanFactory(int points, long expire) {
this.points = points;
this.expiretime = expire;
}
public int getMaximum() {
return points;
}
public long getExpire() {
return expiretime;
}
public void addPoint(AutobanManager ban, String reason) {
if(ServerConstants.USE_AUTOBAN == true) {
ban.addPoint(this, reason);
}
}
public void alert(MapleCharacter chr, String reason) {
if(ServerConstants.USE_AUTOBAN == true) {
FilePrinter.printError("autobanwarning.txt", (chr != null ? MapleCharacter.makeMapleReadable(chr.getName()) : "") + " caused " + this.name() + " " + reason + "\r\n");
if (chr != null && MapleLogger.ignored.contains(chr.getName())){
return;
}
Server.getInstance().broadcastGMMessage(MaplePacketCreator.sendYellowTip((chr != null ? MapleCharacter.makeMapleReadable(chr.getName()) : "") + " caused " + this.name() + " " + reason));
}
}
public void autoban(MapleCharacter chr, String value) {
if(ServerConstants.USE_AUTOBAN == true) {
chr.autoban("Autobanned for (" + this.name() + ": " + value + ")");
//chr.sendPolice("You will be disconnected for (" + this.name() + ": " + value + ")");
}
}
}

View File

@@ -0,0 +1,117 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package client.autoban;
import client.MapleCharacter;
import java.util.HashMap;
import java.util.Map;
import tools.FilePrinter;
/**
*
* @author kevintjuh93
*/
public class AutobanManager {
private MapleCharacter chr;
private Map<AutobanFactory, Integer> points = new HashMap<>();
private Map<AutobanFactory, Long> lastTime = new HashMap<>();
private int misses = 0;
private int lastmisses = 0;
private int samemisscount = 0;
private long spam[] = new long[20];
private int timestamp[] = new int[20];
private byte timestampcounter[] = new byte[20];
public AutobanManager(MapleCharacter chr) {
this.chr = chr;
}
public void addPoint(AutobanFactory fac, String reason) {
if (chr.isGM() || chr.isBanned()){
return;
}
if (lastTime.containsKey(fac)) {
if (lastTime.get(fac) < (System.currentTimeMillis() - fac.getExpire())) {
points.put(fac, points.get(fac) / 2); //So the points are not completely gone.
}
}
if (fac.getExpire() != -1)
lastTime.put(fac, System.currentTimeMillis());
if (points.containsKey(fac)) {
points.put(fac, points.get(fac) + 1);
} else
points.put(fac, 1);
if (points.get(fac) >= fac.getMaximum()) {
chr.autoban(reason);
//chr.autoban("Autobanned for " + fac.name() + " ;" + reason, 1);
//chr.sendPolice("You have been blocked by #bMooplePolice for the HACK reason#k.");
}
// Lets log every single point too.
FilePrinter.printError("autobanwarning.txt", MapleCharacter.makeMapleReadable(chr.getName()) + " caused " + fac.name() + " " + reason + "\r\n");
}
public void addMiss() {
this.misses++;
}
public void resetMisses() {
if (lastmisses == misses && misses > 6) {
samemisscount++;
}
if (samemisscount > 4)
chr.sendPolice("You will be disconnected for miss godmode.");
//chr.autoban("Autobanned for : " + misses + " Miss godmode", 1);
else if (samemisscount > 0)
this.lastmisses = misses;
this.misses = 0;
}
//Don't use the same type for more than 1 thing
public void spam(int type) {
this.spam[type] = System.currentTimeMillis();
}
public void spam(int type, int timestamp) {
this.spam[type] = timestamp;
}
public long getLastSpam(int type) {
return spam[type];
}
/**
* Timestamp checker
*
* <code>type</code>:<br>
* 0: HealOverTime<br>
* 1: Pet Food<br>
* 2: ItemSort<br>
* 3: ItemIdSort<br>
* 4: SpecialMove<br>
* 5: UseCatchItem<br>
* 6: Item Drop<br>
* 7: Chat<br>
*
* @param type type
* @return Timestamp checker
*/
public void setTimestamp(int type, int time, int times) {
if (this.timestamp[type] == time) {
this.timestampcounter[type]++;
if (this.timestampcounter[type] >= times) {
chr.getClient().disconnect(false, false);
//System.out.println("Same timestamp for type: " + type + "; Character: " + chr);
}
return;
}
this.timestamp[type] = time;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,371 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client.inventory;
import client.MapleClient;
import java.util.LinkedList;
import java.util.List;
import server.MapleItemInformationProvider;
import tools.MaplePacketCreator;
import tools.Pair;
public class Equip extends Item {
public static enum ScrollResult {
FAIL(0), SUCCESS(1), CURSE(2);
private int value = -1;
private ScrollResult(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
private byte upgradeSlots;
private byte level, flag, itemLevel;
private short str, dex, _int, luk, hp, mp, watk, matk, wdef, mdef, acc, avoid, hands, speed, jump, vicious;
private float itemExp;
private int ringid = -1;
private boolean wear = false;
public Equip(int id, short position) {
super(id, position, (short) 1);
this.itemExp = 0;
this.itemLevel = 1;
}
public Equip(int id, short position, int slots) {
super(id, position, (short) 1);
this.upgradeSlots = (byte) slots;
this.itemExp = 0;
this.itemLevel = 1;
}
@Override
public Item copy() {
Equip ret = new Equip(getItemId(), getPosition(), getUpgradeSlots());
ret.str = str;
ret.dex = dex;
ret._int = _int;
ret.luk = luk;
ret.hp = hp;
ret.mp = mp;
ret.matk = matk;
ret.mdef = mdef;
ret.watk = watk;
ret.wdef = wdef;
ret.acc = acc;
ret.avoid = avoid;
ret.hands = hands;
ret.speed = speed;
ret.jump = jump;
ret.flag = flag;
ret.vicious = vicious;
ret.upgradeSlots = upgradeSlots;
ret.itemLevel = itemLevel;
ret.itemExp = itemExp;
ret.level = level;
ret.log = new LinkedList<>(log);
ret.setOwner(getOwner());
ret.setQuantity(getQuantity());
ret.setExpiration(getExpiration());
ret.setGiftFrom(getGiftFrom());
return ret;
}
@Override
public byte getFlag() {
return flag;
}
@Override
public byte getType() {
return 1;
}
public byte getUpgradeSlots() {
return upgradeSlots;
}
public short getStr() {
return str;
}
public short getDex() {
return dex;
}
public short getInt() {
return _int;
}
public short getLuk() {
return luk;
}
public short getHp() {
return hp;
}
public short getMp() {
return mp;
}
public short getWatk() {
return watk;
}
public short getMatk() {
return matk;
}
public short getWdef() {
return wdef;
}
public short getMdef() {
return mdef;
}
public short getAcc() {
return acc;
}
public short getAvoid() {
return avoid;
}
public short getHands() {
return hands;
}
public short getSpeed() {
return speed;
}
public short getJump() {
return jump;
}
public short getVicious() {
return vicious;
}
@Override
public void setFlag(byte flag) {
this.flag = flag;
}
public void setStr(short str) {
this.str = str;
}
public void setDex(short dex) {
this.dex = dex;
}
public void setInt(short _int) {
this._int = _int;
}
public void setLuk(short luk) {
this.luk = luk;
}
public void setHp(short hp) {
this.hp = hp;
}
public void setMp(short mp) {
this.mp = mp;
}
public void setWatk(short watk) {
this.watk = watk;
}
public void setMatk(short matk) {
this.matk = matk;
}
public void setWdef(short wdef) {
this.wdef = wdef;
}
public void setMdef(short mdef) {
this.mdef = mdef;
}
public void setAcc(short acc) {
this.acc = acc;
}
public void setAvoid(short avoid) {
this.avoid = avoid;
}
public void setHands(short hands) {
this.hands = hands;
}
public void setSpeed(short speed) {
this.speed = speed;
}
public void setJump(short jump) {
this.jump = jump;
}
public void setVicious(short vicious) {
this.vicious = vicious;
}
public void setUpgradeSlots(byte upgradeSlots) {
this.upgradeSlots = upgradeSlots;
}
public byte getLevel() {
return level;
}
public void setLevel(byte level) {
this.level = level;
}
public void gainLevel(MapleClient c, boolean timeless) {
List<Pair<String, Integer>> stats = MapleItemInformationProvider.getInstance().getItemLevelupStats(getItemId(), itemLevel, timeless);
for (Pair<String, Integer> stat : stats) {
switch (stat.getLeft()) {
case "incDEX":
dex += stat.getRight();
break;
case "incSTR":
str += stat.getRight();
break;
case "incINT":
_int += stat.getRight();
break;
case "incLUK":
luk += stat.getRight();
break;
case "incMHP":
hp += stat.getRight();
break;
case "incMMP":
mp += stat.getRight();
break;
case "incPAD":
watk += stat.getRight();
break;
case "incMAD":
matk += stat.getRight();
break;
case "incPDD":
wdef += stat.getRight();
break;
case "incMDD":
mdef += stat.getRight();
break;
case "incEVA":
avoid += stat.getRight();
break;
case "incACC":
acc += stat.getRight();
break;
case "incSpeed":
speed += stat.getRight();
break;
case "incJump":
jump += stat.getRight();
break;
}
}
this.itemLevel++;
c.announce(MaplePacketCreator.showEquipmentLevelUp());
c.getPlayer().getMap().broadcastMessage(c.getPlayer(), MaplePacketCreator.showForeignEffect(c.getPlayer().getId(), 15));
c.getPlayer().forceUpdateItem(this);
}
public int getItemExp() {
return (int) itemExp;
}
public void gainItemExp(MapleClient c, int gain, boolean timeless) {
int expneeded = timeless ? (10 * itemLevel + 70) : (5 * itemLevel + 65);
float modifier = 364 / expneeded;
float exp = (expneeded / (1000000 * modifier * modifier)) * gain;
itemExp += exp;
if (itemExp >= 364) {
itemExp = (itemExp - 364);
gainLevel(c, timeless);
} else {
c.getPlayer().forceUpdateItem(this);
}
}
public void setItemExp(int exp) {
this.itemExp = exp;
}
public void setItemLevel(byte level) {
this.itemLevel = level;
}
@Override
public void setQuantity(short quantity) {
if (quantity < 0 || quantity > 1) {
throw new RuntimeException("Setting the quantity to " + quantity + " on an equip (itemid: " + getItemId() + ")");
}
super.setQuantity(quantity);
}
public void setUpgradeSlots(int i) {
this.upgradeSlots = (byte) i;
}
public void setVicious(int i) {
this.vicious = (short) i;
}
public int getRingId() {
return ringid;
}
public void setRingId(int id) {
this.ringid = id;
}
public boolean isWearing() {
return wear;
}
public void wear(boolean yes) {
wear = yes;
}
public byte getItemLevel() {
return itemLevel;
}
}

View File

@@ -0,0 +1,172 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client.inventory;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
public class Item implements Comparable<Item> {
private int id, cashId, sn;
private short position;
private short quantity;
private int petid = -1;
private MaplePet pet = null;
private String owner = "";
protected List<String> log;
private byte flag;
private long expiration = -1;
private String giftFrom = "";
public Item(int id, short position, short quantity) {
this.id = id;
this.position = position;
this.quantity = quantity;
this.log = new LinkedList<>();
this.flag = 0;
}
public Item(int id, short position, short quantity, int petid) {
this.id = id;
this.position = position;
this.quantity = quantity;
this.petid = petid;
if (petid > -1) this.pet = MaplePet.loadFromDb(id, position, petid);
this.flag = 0;
this.log = new LinkedList<>();
}
public Item copy() {
Item ret = new Item(id, position, quantity, petid);
ret.flag = flag;
ret.owner = owner;
ret.expiration = expiration;
ret.log = new LinkedList<>(log);
return ret;
}
public void setPosition(short position) {
this.position = position;
}
public void setQuantity(short quantity) {
this.quantity = quantity;
}
public int getItemId() {
return id;
}
public int getCashId() {
if (cashId == 0) {
cashId = new Random().nextInt(Integer.MAX_VALUE) + 1;
}
return cashId;
}
public short getPosition() {
return position;
}
public short getQuantity() {
return quantity;
}
public byte getType() {
if (getPetId() > -1) {
return 3;
}
return 2;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public int getPetId() {
return petid;
}
public void setPetId(int id) {
this.petid = id;
}
public int compareTo(Item other) {
if (this.id < other.getItemId()) {
return -1;
} else if (this.id > other.getItemId()) {
return 1;
}
return 0;
}
@Override
public String toString() {
return "Item: " + id + " quantity: " + quantity;
}
public List<String> getLog() {
return Collections.unmodifiableList(log);
}
public byte getFlag() {
return flag;
}
public void setFlag(byte b) {
this.flag = b;
}
public long getExpiration() {
return expiration;
}
public void setExpiration(long expire) {
this.expiration = expire;
}
public int getSN() {
return sn;
}
public void setSN(int sn) {
this.sn = sn;
}
public String getGiftFrom() {
return giftFrom;
}
public void setGiftFrom(String giftFrom) {
this.giftFrom = giftFrom;
}
public MaplePet getPet() {
return pet;
}
}

View File

@@ -0,0 +1,227 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 client.inventory;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
import tools.DatabaseConnection;
import tools.Pair;
/**
*
* @author Flav
*/
public enum ItemFactory {
INVENTORY(1, false),
STORAGE(2, true),
CASH_EXPLORER(3, true),
CASH_CYGNUS(4, false),
CASH_ARAN(5, false),
MERCHANT(6, false);
private int value;
private boolean account;
private static ReentrantLock lock = new ReentrantLock(true);
private ItemFactory(int value, boolean account) {
this.value = value;
this.account = account;
}
public int getValue() {
return value;
}
public List<Pair<Item, MapleInventoryType>> loadItems(int id, boolean login) throws SQLException {
List<Pair<Item, MapleInventoryType>> items = new ArrayList<>();
PreparedStatement ps = null;
ResultSet rs = null;
try {
StringBuilder query = new StringBuilder();
query.append("SELECT * FROM `inventoryitems` LEFT JOIN `inventoryequipment` USING(`inventoryitemid`) WHERE `type` = ? AND `");
query.append(account ? "accountid" : "characterid").append("` = ?");
if (login) {
query.append(" AND `inventorytype` = ").append(MapleInventoryType.EQUIPPED.getType());
}
ps = DatabaseConnection.getConnection().prepareStatement(query.toString());
ps.setInt(1, value);
ps.setInt(2, id);
rs = ps.executeQuery();
while (rs.next()) {
MapleInventoryType mit = MapleInventoryType.getByType(rs.getByte("inventorytype"));
if (mit.equals(MapleInventoryType.EQUIP) || mit.equals(MapleInventoryType.EQUIPPED)) {
Equip equip = new Equip(rs.getInt("itemid"), (byte) rs.getInt("position"));
equip.setOwner(rs.getString("owner"));
equip.setQuantity((short) rs.getInt("quantity"));
equip.setAcc((short) rs.getInt("acc"));
equip.setAvoid((short) rs.getInt("avoid"));
equip.setDex((short) rs.getInt("dex"));
equip.setHands((short) rs.getInt("hands"));
equip.setHp((short) rs.getInt("hp"));
equip.setInt((short) rs.getInt("int"));
equip.setJump((short) rs.getInt("jump"));
equip.setVicious((short) rs.getInt("vicious"));
equip.setFlag((byte) rs.getInt("flag"));
equip.setLuk((short) rs.getInt("luk"));
equip.setMatk((short) rs.getInt("matk"));
equip.setMdef((short) rs.getInt("mdef"));
equip.setMp((short) rs.getInt("mp"));
equip.setSpeed((short) rs.getInt("speed"));
equip.setStr((short) rs.getInt("str"));
equip.setWatk((short) rs.getInt("watk"));
equip.setWdef((short) rs.getInt("wdef"));
equip.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
equip.setLevel((byte) rs.getByte("level"));
equip.setItemExp(rs.getInt("itemexp"));
equip.setItemLevel(rs.getByte("itemlevel"));
equip.setExpiration(rs.getLong("expiration"));
equip.setGiftFrom(rs.getString("giftFrom"));
equip.setRingId(rs.getInt("ringid"));
items.add(new Pair<Item, MapleInventoryType>(equip, mit));
} else {
Item item = new Item(rs.getInt("itemid"), (byte) rs.getInt("position"), (short) rs.getInt("quantity"), rs.getInt("petid"));
item.setOwner(rs.getString("owner"));
item.setExpiration(rs.getLong("expiration"));
item.setGiftFrom(rs.getString("giftFrom"));
item.setFlag((byte) rs.getInt("flag"));
items.add(new Pair<>(item, mit));
}
}
rs.close();
ps.close();
} finally {
if (rs != null) {
rs.close();
}
if (ps != null) {
ps.close();
}
}
return items;
}
public synchronized void saveItems(List<Pair<Item, MapleInventoryType>> items, int id, Connection con) throws SQLException {
PreparedStatement ps = null;
PreparedStatement pse = null;
ResultSet rs = null;
lock.lock();
try {
StringBuilder query = new StringBuilder();
query.append("DELETE `inventoryitems`, `inventoryequipment` FROM `inventoryitems` LEFT JOIN `inventoryequipment` USING(`inventoryitemid`) WHERE `type` = ? AND `");
query.append(account ? "accountid" : "characterid").append("` = ?");
ps = con.prepareStatement(query.toString());
ps.setInt(1, value);
ps.setInt(2, id);
ps.executeUpdate();
ps.close();
ps = con.prepareStatement("INSERT INTO `inventoryitems` VALUES (DEFAULT, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS);
if (!items.isEmpty()) {
for (Pair<Item, MapleInventoryType> pair : items) {
Item item = pair.getLeft();
MapleInventoryType mit = pair.getRight();
ps.setInt(1, value);
ps.setString(2, account ? null : String.valueOf(id));
ps.setString(3, account ? String.valueOf(id) : null);
ps.setInt(4, item.getItemId());
ps.setInt(5, mit.getType());
ps.setInt(6, item.getPosition());
ps.setInt(7, item.getQuantity());
ps.setString(8, item.getOwner());
ps.setInt(9, item.getPetId());
ps.setInt(10, item.getFlag());
ps.setLong(11, item.getExpiration());
ps.setString(12, item.getGiftFrom());
ps.executeUpdate();
pse = con.prepareStatement("INSERT INTO `inventoryequipment` VALUES (DEFAULT, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
if (mit.equals(MapleInventoryType.EQUIP) || mit.equals(MapleInventoryType.EQUIPPED)) {
rs = ps.getGeneratedKeys();
if (!rs.next()) {
throw new RuntimeException("Inserting item failed.");
}
pse.setInt(1, rs.getInt(1));
rs.close();
Equip equip = (Equip) item;
pse.setInt(2, equip.getUpgradeSlots());
pse.setInt(3, equip.getLevel());
pse.setInt(4, equip.getStr());
pse.setInt(5, equip.getDex());
pse.setInt(6, equip.getInt());
pse.setInt(7, equip.getLuk());
pse.setInt(8, equip.getHp());
pse.setInt(9, equip.getMp());
pse.setInt(10, equip.getWatk());
pse.setInt(11, equip.getMatk());
pse.setInt(12, equip.getWdef());
pse.setInt(13, equip.getMdef());
pse.setInt(14, equip.getAcc());
pse.setInt(15, equip.getAvoid());
pse.setInt(16, equip.getHands());
pse.setInt(17, equip.getSpeed());
pse.setInt(18, equip.getJump());
pse.setInt(19, 0);
pse.setInt(20, equip.getVicious());
pse.setInt(21, equip.getItemLevel());
pse.setInt(22, equip.getItemExp());
pse.setInt(23, equip.getRingId());
pse.executeUpdate();
}
pse.close();
}
}
ps.close();
} finally {
if (ps != null && !ps.isClosed()) {
ps.close();
}
if (pse != null && !pse.isClosed()) {
pse.close();
}
if(rs != null && !rs.isClosed()) {
rs.close();
}
lock.unlock();
}
}
}

View File

@@ -0,0 +1,281 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client.inventory;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import tools.Pair;
import client.MapleCharacter;
import constants.ItemConstants;
/**
*
* @author Matze
*/
public class MapleInventory implements Iterable<Item> {
private Map<Short, Item> inventory = new LinkedHashMap<>();
private byte slotLimit;
private MapleInventoryType type;
private boolean checked = false;
public MapleInventory(MapleInventoryType type, byte slotLimit) {
this.inventory = new LinkedHashMap<>();
this.type = type;
this.slotLimit = slotLimit;
}
public boolean isExtendableInventory() { // not sure about cash, basing this on the previous one.
return !(type.equals(MapleInventoryType.UNDEFINED) || type.equals(MapleInventoryType.EQUIPPED) || type.equals(MapleInventoryType.CASH));
}
public boolean isEquipInventory() {
return type.equals(MapleInventoryType.EQUIP) || type.equals(MapleInventoryType.EQUIPPED);
}
public byte getSlotLimit() {
return slotLimit;
}
public void setSlotLimit(int newLimit) {
slotLimit = (byte) newLimit;
}
public Item findById(int itemId) {
for (Item item : inventory.values()) {
if (item.getItemId() == itemId) {
return item;
}
}
return null;
}
public int countById(int itemId) {
int possesed = 0;
for (Item item : inventory.values()) {
if (item.getItemId() == itemId) {
possesed += item.getQuantity();
}
}
return possesed;
}
public List<Item> listById(int itemId) {
List<Item> ret = new ArrayList<>();
for (Item item : inventory.values()) {
if (item.getItemId() == itemId) {
ret.add(item);
}
}
if (ret.size() > 1) {
Collections.sort(ret);
}
return ret;
}
public Collection<Item> list() {
return inventory.values();
}
public short addItem(Item item) {
short slotId = getNextFreeSlot();
if (slotId < 0 || item == null) {
return -1;
}
inventory.put(slotId, item);
item.setPosition(slotId);
return slotId;
}
public void addFromDB(Item item) {
if (item.getPosition() < 0 && !type.equals(MapleInventoryType.EQUIPPED)) {
return;
}
inventory.put(item.getPosition(), item);
}
public void move(short sSlot, short dSlot, short slotMax) {
Item source = (Item) inventory.get(sSlot);
Item target = (Item) inventory.get(dSlot);
if (source == null) {
return;
}
if (target == null) {
source.setPosition(dSlot);
inventory.put(dSlot, source);
inventory.remove(sSlot);
} else if (target.getItemId() == source.getItemId() && !ItemConstants.isRechargable(source.getItemId())) {
if (type.getType() == MapleInventoryType.EQUIP.getType()) {
swap(target, source);
}
if (source.getQuantity() + target.getQuantity() > slotMax) {
short rest = (short) ((source.getQuantity() + target.getQuantity()) - slotMax);
source.setQuantity(rest);
target.setQuantity(slotMax);
} else {
target.setQuantity((short) (source.getQuantity() + target.getQuantity()));
inventory.remove(sSlot);
}
} else {
swap(target, source);
}
}
private void swap(Item source, Item target) {
inventory.remove(source.getPosition());
inventory.remove(target.getPosition());
short swapPos = source.getPosition();
source.setPosition(target.getPosition());
target.setPosition(swapPos);
inventory.put(source.getPosition(), source);
inventory.put(target.getPosition(), target);
}
public Item getItem(short slot) {
return inventory.get(slot);
}
public void removeItem(short slot) {
removeItem(slot, (short) 1, false);
}
public void removeItem(short slot, short quantity, boolean allowZero) {
Item item = inventory.get(slot);
if (item == null) {// TODO is it ok not to throw an exception here?
return;
}
item.setQuantity((short) (item.getQuantity() - quantity));
if (item.getQuantity() < 0) {
item.setQuantity((short) 0);
}
if (item.getQuantity() == 0 && !allowZero) {
removeSlot(slot);
}
}
public void removeSlot(short slot) {
inventory.remove(slot);
}
public boolean isFull() {
return inventory.size() >= slotLimit;
}
public boolean isFull(int margin) {
return inventory.size() + margin >= slotLimit;
}
public short getNextFreeSlot() {
if (isFull()) {
return -1;
}
for (short i = 1; i <= slotLimit; i++) {
if (!inventory.keySet().contains(i)) {
return i;
}
}
return -1;
}
public short getNumFreeSlot() {
if (isFull()) {
return 0;
}
short free = 0;
for (short i = 1; i <= slotLimit; i++) {
if (!inventory.keySet().contains(i)) {
free++;
}
}
return free;
}
public static boolean checkSpot(MapleCharacter chr, Item item) {
if (chr.getInventory(MapleInventoryType.getByType(item.getType())).isFull()) return false;
return true;
}
public static boolean checkSpots(MapleCharacter chr, List<Pair<Item, MapleInventoryType>> items) {
int equipSlot = 0, useSlot = 0, setupSlot = 0, etcSlot = 0, cashSlot = 0;
for (Pair<Item, MapleInventoryType> item : items) {
if (item.getRight().getType() == MapleInventoryType.EQUIP.getType())
equipSlot++;
if (item.getRight().getType() == MapleInventoryType.USE.getType())
useSlot++;
if (item.getRight().getType() == MapleInventoryType.SETUP.getType())
setupSlot++;
if (item.getRight().getType() == MapleInventoryType.ETC.getType())
etcSlot++;
if (item.getRight().getType() == MapleInventoryType.CASH.getType())
cashSlot++;
}
if (chr.getInventory(MapleInventoryType.EQUIP).isFull(equipSlot - 1)) return false;
else if (chr.getInventory(MapleInventoryType.USE).isFull(useSlot - 1)) return false;
else if (chr.getInventory(MapleInventoryType.SETUP).isFull(setupSlot - 1)) return false;
else if (chr.getInventory(MapleInventoryType.ETC).isFull(etcSlot - 1)) return false;
else if (chr.getInventory(MapleInventoryType.CASH).isFull(cashSlot - 1)) return false;
return true;
}
public MapleInventoryType getType() {
return type;
}
@Override
public Iterator<Item> iterator() {
return Collections.unmodifiableCollection(inventory.values()).iterator();
}
public Collection<MapleInventory> allInventories() {
return Collections.singletonList(this);
}
public Item findByCashId(int cashId) {
boolean isRing = false;
Equip equip = null;
for (Item item : inventory.values()) {
if (item.getType() == MapleInventoryType.EQUIP.getType()) {
equip = (Equip) item;
isRing = equip.getRingId() > -1;
}
if ((item.getPetId() > -1 ? item.getPetId() : isRing ? equip.getRingId() : item.getCashId()) == cashId)
return item;
}
return null;
}
public boolean checked() {
return checked;
}
public void checked(boolean yes) {
checked = yes;
}
}

View File

@@ -0,0 +1,72 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client.inventory;
/**
* @author Matze
*/
public enum MapleInventoryType {
UNDEFINED(0),
EQUIP(1),
USE(2),
SETUP(3),
ETC(4),
CASH(5),
EQUIPPED(-1); //Seems nexon screwed something when removing an item T_T
final byte type;
private MapleInventoryType(int type) {
this.type = (byte) type;
}
public byte getType() {
return type;
}
public short getBitfieldEncoding() {
return (short) (2 << type);
}
public static MapleInventoryType getByType(byte type) {
for (MapleInventoryType l : MapleInventoryType.values()) {
if (l.getType() == type) {
return l;
}
}
return null;
}
public static MapleInventoryType getByWZName(String name) {
if (name.equals("Install")) {
return SETUP;
} else if (name.equals("Consume")) {
return USE;
} else if (name.equals("Etc")) {
return ETC;
} else if (name.equals("Cash")) {
return CASH;
} else if (name.equals("Pet")) {
return CASH;
}
return UNDEFINED;
}
}

View File

@@ -0,0 +1,229 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client.inventory;
import com.mysql.jdbc.Statement;
import java.awt.Point;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import tools.DatabaseConnection;
import server.MapleItemInformationProvider;
import server.movement.AbsoluteLifeMovement;
import server.movement.LifeMovement;
import server.movement.LifeMovementFragment;
/**
*
* @author Matze
*/
public class MaplePet extends Item {
private String name;
private int uniqueid;
private int closeness = 0;
private byte level = 1;
private int fullness = 100;
private int Fh;
private Point pos;
private int stance;
private boolean summoned;
private MaplePet(int id, short position, int uniqueid) {
super(id, position, (short) 1);
this.uniqueid = uniqueid;
}
public static MaplePet loadFromDb(int itemid, short position, int petid) {
try {
MaplePet ret = new MaplePet(itemid, position, petid);
PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("SELECT name, level, closeness, fullness, summoned FROM pets WHERE petid = ?"); // Get pet details..
ps.setInt(1, petid);
ResultSet rs = ps.executeQuery();
rs.next();
ret.setName(rs.getString("name"));
ret.setCloseness(Math.min(rs.getInt("closeness"), 30000));
ret.setLevel((byte) Math.min(rs.getByte("level"), 30));
ret.setFullness(Math.min(rs.getInt("fullness"), 100));
ret.setSummoned(rs.getInt("summoned") == 1);
rs.close();
ps.close();
return ret;
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
public void saveToDb() {
try {
PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("UPDATE pets SET name = ?, level = ?, closeness = ?, fullness = ?, summoned = ? WHERE petid = ?");
ps.setString(1, getName());
ps.setInt(2, getLevel());
ps.setInt(3, getCloseness());
ps.setInt(4, getFullness());
ps.setInt(5, isSummoned() ? 1 : 0);
ps.setInt(6, getUniqueId());
ps.executeUpdate();
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static int createPet(int itemid) {
try {
PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("INSERT INTO pets (name, level, closeness, fullness, summoned) VALUES (?, 1, 0, 100, 0)", Statement.RETURN_GENERATED_KEYS);
ps.setString(1, MapleItemInformationProvider.getInstance().getName(itemid));
ps.executeUpdate();
ResultSet rs = ps.getGeneratedKeys();
int ret = -1;
if (rs.next()) {
ret = rs.getInt(1);
}
rs.close();
ps.close();
return ret;
} catch (SQLException e) {
e.printStackTrace();
return -1;
}
}
public static int createPet(int itemid, byte level, int closeness, int fullness) {
try {
PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("INSERT INTO pets (name, level, closeness, fullness, summoned) VALUES (?, ?, ?, ?, 0)", Statement.RETURN_GENERATED_KEYS);
ps.setString(1, MapleItemInformationProvider.getInstance().getName(itemid));
ps.setByte(2, level);
ps.setInt(3, closeness);
ps.setInt(4, fullness);
ps.executeUpdate();
ResultSet rs = ps.getGeneratedKeys();
int ret = -1;
if (rs.next()) {
ret = rs.getInt(1);
rs.close();
ps.close();
}
return ret;
} catch (SQLException e) {
e.printStackTrace();
return -1;
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getUniqueId() {
return uniqueid;
}
public void setUniqueId(int id) {
this.uniqueid = id;
}
public int getCloseness() {
return closeness;
}
public void setCloseness(int closeness) {
this.closeness = closeness;
}
public void gainCloseness(int x) {
this.closeness += x;
}
public byte getLevel() {
return level;
}
public void setLevel(byte level) {
this.level = level;
}
public int getFullness() {
return fullness;
}
public void setFullness(int fullness) {
this.fullness = fullness;
}
public int getFh() {
return Fh;
}
public void setFh(int Fh) {
this.Fh = Fh;
}
public Point getPos() {
return pos;
}
public void setPos(Point pos) {
this.pos = pos;
}
public int getStance() {
return stance;
}
public void setStance(int stance) {
this.stance = stance;
}
public boolean isSummoned() {
return summoned;
}
public void setSummoned(boolean yes) {
this.summoned = yes;
}
public boolean canConsume(int itemId) {
for (int petId : MapleItemInformationProvider.getInstance().petsCanConsume(itemId)) {
if (petId == this.getItemId()) {
return true;
}
}
return false;
}
public void updatePosition(List<LifeMovementFragment> movement) {
for (LifeMovementFragment move : movement) {
if (move instanceof LifeMovement) {
if (move instanceof AbsoluteLifeMovement) {
this.setPos(((LifeMovement) move).getPosition());
}
this.setStance(((LifeMovement) move).getNewstate());
}
}
}
}

View File

@@ -0,0 +1,54 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client.inventory;
public enum MapleWeaponType {
NOT_A_WEAPON(0),
GENERAL1H_SWING(4.4),
GENERAL1H_STAB(3.2),
GENERAL2H_SWING(4.8),
GENERAL2H_STAB(3.4),
BOW(3.4),
CLAW(3.6),
CROSSBOW(3.6),
DAGGER_THIEVES(3.6),
DAGGER_OTHER(4),
GUN(3.6),
KNUCKLE(4.8),
POLE_ARM_SWING(5.0),
POLE_ARM_STAB(3.0),
SPEAR_STAB(5.0),
SPEAR_SWING(3.0),
STAFF(3.6),
SWORD1H(4.0),
SWORD2H(4.6),
WAND(3.6);
private double damageMultiplier;
private MapleWeaponType(double maxDamageMultiplier) {
this.damageMultiplier = maxDamageMultiplier;
}
public double getMaxDamageMultiplier() {
return damageMultiplier;
}
}

View File

@@ -0,0 +1,53 @@
package client.inventory;
import constants.ItemConstants;
/**
*
* @author kevin
*/
public class ModifyInventory {
private int mode;
private Item item;
private short oldPos;
public ModifyInventory(final int mode, final Item item) {
this.mode = mode;
this.item = item.copy();
}
public ModifyInventory(final int mode, final Item item, final short oldPos) {
this.mode = mode;
this.item = item.copy();
this.oldPos = oldPos;
}
public final int getMode() {
return mode;
}
public final int getInventoryType() {
return ItemConstants.getInventoryType(item.getItemId()).getType();
}
public final short getPosition() {
return item.getPosition();
}
public final short getOldPosition() {
return oldPos;
}
public final short getQuantity() {
return item.getQuantity();
}
public final Item getItem() {
return item;
}
public final void clear() {
this.item = null;
}
}

View File

@@ -0,0 +1,52 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client.inventory;
/*
* @author Leifde
*/
public class PetCommand {
private int petId, skillId, prob, inc;
public PetCommand(int petId, int skillId, int prob, int inc) {
this.petId = petId;
this.skillId = skillId;
this.prob = prob;
this.inc = inc;
}
public int getPetId() {
return petId;
}
public int getSkillId() {
return skillId;
}
public int getProbability() {
return prob;
}
public int getIncrease() {
return inc;
}
}

View File

@@ -0,0 +1,76 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client.inventory;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import provider.MapleData;
import provider.MapleDataProvider;
import provider.MapleDataProviderFactory;
import provider.MapleDataTool;
/**
*
* @author Danny (Leifde)
*/
public class PetDataFactory {
private static MapleDataProvider dataRoot = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Item.wz"));
private static Map<String, PetCommand> petCommands = new HashMap<String, PetCommand>();
private static Map<Integer, Integer> petHunger = new HashMap<Integer, Integer>();
public static PetCommand getPetCommand(int petId, int skillId) {
PetCommand ret = petCommands.get(Integer.valueOf(petId) + "" + skillId);
if (ret != null) {
return ret;
}
synchronized (petCommands) {
ret = petCommands.get(petId + "" + skillId);
if (ret == null) {
MapleData skillData = dataRoot.getData("Pet/" + petId + ".img");
int prob = 0;
int inc = 0;
if (skillData != null) {
prob = MapleDataTool.getInt("interact/" + skillId + "/prob", skillData, 0);
inc = MapleDataTool.getInt("interact/" + skillId + "/inc", skillData, 0);
}
ret = new PetCommand(petId, skillId, prob, inc);
petCommands.put(petId + "" + skillId, ret);
}
return ret;
}
}
public static int getHunger(int petId) {
Integer ret = petHunger.get(Integer.valueOf(petId));
if (ret != null) {
return ret;
}
synchronized (petHunger) {
ret = petHunger.get(Integer.valueOf(petId));
if (ret == null) {
ret = Integer.valueOf(MapleDataTool.getInt(dataRoot.getData("Pet/" + petId + ".img").getChildByPath("info/hungry"), 1));
}
return ret;
}
}
}

View File

@@ -0,0 +1,77 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client.status;
public enum MonsterStatus {
WATK(0x1),
WDEF(0x2),
NEUTRALISE(0x2, true),
PHANTOM_IMPRINT(0x4, true), // needs testing
MATK(0x4),
MDEF(0x8),
ACC(0x10),
AVOID(0x20),
SPEED(0x40),
STUN(0x80),
FREEZE(0x100),
POISON(0x200),
SEAL(0x400),
SHOWDOWN(0x800),
WEAPON_ATTACK_UP(0x1000),
WEAPON_DEFENSE_UP(0x2000),
MAGIC_ATTACK_UP(0x4000),
MAGIC_DEFENSE_UP(0x8000),
DOOM(0x10000),
SHADOW_WEB(0x20000),
WEAPON_IMMUNITY(0x40000),
MAGIC_IMMUNITY(0x80000),
HARD_SKIN(0x200000), // just added
NINJA_AMBUSH(0x400000),
ELEMENTAL_ATTRIBUTE(0x800000), // just added
VENOMOUS_WEAPON(0x1000000),
BLIND(0x2000000), // just added
SEAL_SKILL(0x4000000),
INERTMOB(0x10000000),
WEAPON_REFLECT(0x20000000, true),
MAGIC_REFLECT(0x40000000, true);
private final int i;
private final boolean first;
private MonsterStatus(int i) {
this.i = i;
this.first = false;
}
private MonsterStatus(int i, boolean first) {
this.i = i;
this.first = first;
}
public boolean isFirst() {
return first;
}
public int getValue() {
return i;
}
}

View File

@@ -0,0 +1,94 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 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 as
published by the Free Software Foundation 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 client.status;
import client.Skill;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;
import server.life.MobSkill;
import tools.ArrayMap;
public class MonsterStatusEffect {
private Map<MonsterStatus, Integer> stati;
private Skill skill;
private MobSkill mobskill;
private boolean monsterSkill;
private ScheduledFuture<?> cancelTask;
private ScheduledFuture<?> damageSchedule;
public MonsterStatusEffect(Map<MonsterStatus, Integer> stati, Skill skillId, MobSkill mobskill, boolean monsterSkill) {
this.stati = new ArrayMap<>(stati);
this.skill = skillId;
this.monsterSkill = monsterSkill;
this.mobskill = mobskill;
}
public Map<MonsterStatus, Integer> getStati() {
return stati;
}
public Integer setValue(MonsterStatus status, Integer newVal) {
return stati.put(status, newVal);
}
public Skill getSkill() {
return skill;
}
public boolean isMonsterSkill() {
return monsterSkill;
}
public final void cancelTask() {
if (cancelTask != null) {
cancelTask.cancel(false);
}
cancelTask = null;
}
public ScheduledFuture<?> getCancelTask() {
return cancelTask;
}
public void setCancelTask(ScheduledFuture<?> cancelTask) {
this.cancelTask = cancelTask;
}
public void removeActiveStatus(MonsterStatus stat) {
stati.remove(stat);
}
public void setDamageSchedule(ScheduledFuture<?> damageSchedule) {
this.damageSchedule = damageSchedule;
}
public void cancelDamageSchedule() {
if (damageSchedule != null) {
damageSchedule.cancel(false);
}
}
public MobSkill getMobSkill() {
return mobskill;
}
}