This commit is contained in:
Lenheart 2025-03-03 15:16:22 +08:00 committed by 雪风
commit 18a1f4b24e
582 changed files with 151426 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.idea/
out/

12
A079.iml Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="lib" level="project" />
</component>
</module>

BIN
lib/US_export_policy.jar Normal file

Binary file not shown.

BIN
lib/beansbinding-1.2.1.jar Normal file

Binary file not shown.

BIN
lib/beautyeye_lnf.jar Normal file

Binary file not shown.

BIN
lib/classfinal-fatjar.jar Normal file

Binary file not shown.

BIN
lib/druid-1.0.27.jar Normal file

Binary file not shown.

BIN
lib/fastjson-1.2.74.jar Normal file

Binary file not shown.

BIN
lib/hutool-all-5.8.26.jar Normal file

Binary file not shown.

BIN
lib/local_policy.jar Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

30
src/MXDJR/BuildPack.java Normal file
View File

@ -0,0 +1,30 @@
package MXDJR;
import java.nio.charset.StandardCharsets;
import com.alibaba.fastjson.JSON;
class BuildPack {
public static byte[] Build(final Object data, final int index) {
final String str = JSON.toJSONString(data) + " ";
final byte[] temp = str.getBytes(StandardCharsets.UTF_8);
temp[temp.length - 1] = (byte) index;
return temp;
}
public static byte[] BuildImage(final long qq, final long id, final long fid, final String img, final int index) {
String temp = "";
if (id != 0L) {
temp = temp + "id=" + id + "&";
}
if (fid != 0L) {
temp = temp + "fid=" + fid + "&";
}
temp = temp + "qq=" + qq + "&";
temp = temp + "img=" + img;
final String str = temp + " ";
final byte[] temp2 = str.getBytes(StandardCharsets.UTF_8);
temp2[temp2.length - 1] = (byte) index;
return temp2;
}
}

12
src/MXDJR/ConfigObj.java Normal file
View File

@ -0,0 +1,12 @@
package MXDJR;
import java.util.ArrayList;
import java.util.List;
public class ConfigObj {
public List<String> GJC;
public ConfigObj() {
this.GJC = (List<String>) new ArrayList();
}
}

67
src/MXDJR/ConfigRead.java Normal file
View File

@ -0,0 +1,67 @@
package MXDJR;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.FileOutputStream;
import java.util.Iterator;
import java.io.IOException;
import com.alibaba.fastjson.JSON;
import java.io.Reader;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.io.FileInputStream;
import java.io.File;
public class ConfigRead {
private static File ConfigFile;
public static boolean ReadStart(final String local) {
try {
ConfigRead.ConfigFile = new File(local + "AnswerConfig.json");
if (!ConfigRead.ConfigFile.exists()) {
ConfigRead.ConfigFile.createNewFile();
MXDJR.Config = new ConfigObj();
Save();
return true;
}
final InputStreamReader reader = new InputStreamReader((InputStream) new FileInputStream(ConfigRead.ConfigFile), StandardCharsets.UTF_8);
final BufferedReader bf = new BufferedReader((Reader) reader);
final char[] buf = new char[1024];
final StringBuilder data = new StringBuilder();
int length;
while ((length = bf.read(buf)) != -1) {
data.append(new String(buf, 0, length));
}
MXDJR.Config = (ConfigObj) JSON.parseObject(data.toString(), ConfigObj.class);
if (MXDJR.Config.GJC == null) {
MXDJR.Config = new ConfigObj();
Save();
}
bf.close();
reader.close();
for (final String item : MXDJR.Config.GJC) {
System.out.println("关键词:" + item);
}
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
public static void Save() {
try {
final FileOutputStream out = new FileOutputStream(ConfigRead.ConfigFile);
final OutputStreamWriter write = new OutputStreamWriter((OutputStream) out, StandardCharsets.UTF_8);
write.write(JSON.toJSONString(MXDJR.Config));
write.close();
out.close();
} catch (Exception e) {
System.out.println("配置文件保存失败:" + e);
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,10 @@
package MXDJR;
import java.util.List;
class FriendMessageEventPack extends PackBase {
public long id;
public String name;
public List<String> message;
public int time;
}

View File

@ -0,0 +1,10 @@
package MXDJR;
import java.util.List;
class GroupMessageEventPack extends PackBase {
public long id;
public long fid;
public String name;
public List<String> message;
}

22
src/MXDJR/MXDJR.java Normal file
View File

@ -0,0 +1,22 @@
package MXDJR;
public class MXDJR {
public static String RunDir;
public static ConfigObj Config;
public static void startJR() {
if (RobotSocket.IsRun) {
System.out.println("机器人已经启动了,本次关闭了机器人。");
RobotSocket.Stop();
return;
}
MXDJR.RunDir = System.getProperty("user.dir") + "/";
System.out.println("正在启动群机器人……");
if (ConfigRead.ReadStart(MXDJR.RunDir)) {
System.out.println("请修改配置文件后重新点击!");
return;
}
System.out.println("初始化完成,一共获取到" + MXDJR.Config.GJC.size() + "个关键词!");
RobotSocket.Start();
}
}

5
src/MXDJR/PackBase.java Normal file
View File

@ -0,0 +1,5 @@
package MXDJR;
abstract class PackBase {
public long qq;
}

266
src/MXDJR/RobotSocket.java Normal file
View File

@ -0,0 +1,266 @@
package MXDJR;
import java.util.ArrayList;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import handling.world.World.Broadcast;
import tools.MaplePacketCreator;
import com.alibaba.fastjson.JSON;
import java.util.concurrent.CopyOnWriteArrayList;
import constants.ServerConfig;
import java.util.List;
import java.net.Socket;
public class RobotSocket {
private static Socket Socket;
private static Thread ReadThread;
private static Thread DoThread;
public static boolean IsRun;
public static boolean IsConnect;
private static List<RobotTask> QueueRead;
private static List<byte[]> QueueSend;
private static int Num;
private static String list;
private static long[] QQ号;
private static long[] QQ群号;
private static long[] QQ群主;
private static final StartPack PackStart;
public static long QQ号() {
return RobotSocket.QQ号[ServerConfig.nub1];
}
public static long QQ群号() {
return RobotSocket.QQ群号[ServerConfig.nub1];
}
public static long QQ群主() {
return RobotSocket.QQ群主[ServerConfig.nub1];
}
public static void Start() {
RobotSocket.QueueRead = (List<RobotTask>) new CopyOnWriteArrayList();
RobotSocket.QueueSend = (List<byte[]>) new CopyOnWriteArrayList();
RobotSocket.DoThread = new Thread((Runnable) new Runnable() {
@Override
public void run() {
while (RobotSocket.IsRun) {
try {
if (!RobotSocket.QueueRead.isEmpty()) {
final RobotTask task = (RobotTask) RobotSocket.QueueRead.remove(0);
switch (task.index) {
case 49: {
final GroupMessageEventPack pack = (GroupMessageEventPack) JSON.parseObject(task.data, GroupMessageEventPack.class);
final String item = (String) pack.message.get(1);
if (!item.contains((CharSequence) "{") && !item.contains((CharSequence) "[")) {
Broadcast.broadcastMessage(MaplePacketCreator.serverNotice(6, "[群消息]" + pack.name + "->" + item));
}
if (item.contains((CharSequence) "增加关键字") && pack.fid == RobotSocket.QQ群主[ServerConfig.nub1]) {
final String 关键字 = item.substring(item.indexOf("") + 1);
System.out.println("增加游戏内关键字:" + 关键字);
MXDJR.Config.GJC.add(关键字);
ConfigRead.Save();
final List<String> send = Arrays.asList("我已经开通关键字:" + 关键字);
RobotSocket.SendGroupMessage(RobotSocket.QQ号[ServerConfig.nub1], RobotSocket.QQ群号[ServerConfig.nub1], send);
break;
}
if (item.contains((CharSequence) "删除关键字") && pack.fid == RobotSocket.QQ群主[ServerConfig.nub1]) {
final String 关键字 = item.substring(item.indexOf("") + 1);
System.out.println("删除游戏内关键字:" + 关键字);
for (int num = 0; num < MXDJR.Config.GJC.size(); ++num) {
if (((String) MXDJR.Config.GJC.get(num)).contains((CharSequence) 关键字)) {
MXDJR.Config.GJC.remove(num);
ConfigRead.Save();
final List<String> send2 = Arrays.asList("我已经删除关键字:" + 关键字);
RobotSocket.SendGroupMessage(RobotSocket.QQ号[ServerConfig.nub1], RobotSocket.QQ群号[ServerConfig.nub1], send2);
break;
}
}
}
if (item.contains((CharSequence) "查看关键字")) {
String 关键字2 = "";
for (int num2 = 0; num2 < MXDJR.Config.GJC.size(); ++num2) {
关键字2 = 关键字2 + "" + (String) MXDJR.Config.GJC.get(num2) + "";
}
final List<String> send2 = Arrays.asList("游戏通告支持关键字:" + 关键字2);
RobotSocket.SendGroupMessage(RobotSocket.QQ号[ServerConfig.nub1], RobotSocket.QQ群号[ServerConfig.nub1], send2);
break;
}
break;
}
}
}
Thread.sleep(10L);
} catch (Exception e) {
ServerMain.LogError(e);
}
}
}
});
(RobotSocket.ReadThread = new Thread((Runnable) new Runnable() {
@Override
public void run() {
try {
while (!RobotSocket.IsRun) {
Thread.sleep(100L);
}
} catch (Exception e) {
ServerMain.LogError(e);
}
RobotSocket.DoThread.start();
while (RobotSocket.IsRun) {
try {
if (!RobotSocket.IsConnect) {
ReConnect();
} else {
if (RobotSocket.Socket.getInputStream().available() > 0) {
final byte[] data = new byte[RobotSocket.Socket.getInputStream().available()];
RobotSocket.Socket.getInputStream().read(data);
final byte type = data[data.length - 1];
data[data.length - 1] = 0;
final String unicode = new String(data, "UTF-8");
final String gbk = new String(unicode.getBytes("GBK"));
RobotSocket.QueueRead.add(new RobotTask(type, gbk));
continue;
}
if (RobotSocket.Socket.getInputStream().available() < 0) {
ServerMain.LogOut("机器人连接中断");
RobotSocket.IsConnect = false;
} else if (!RobotSocket.QueueSend.isEmpty()) {
final byte[] data = (byte[]) RobotSocket.QueueSend.remove(0);
RobotSocket.Socket.getOutputStream().write(data);
RobotSocket.Socket.getOutputStream().flush();
}
}
Thread.sleep(50L);
} catch (Exception e2) {
ServerMain.LogError("机器人连接失败");
ServerMain.LogError(e2);
RobotSocket.IsConnect = false;
ServerMain.LogError("机器人20秒后重连");
try {
Thread.sleep(20000L);
} catch (InterruptedException interruptedException) {
interruptedException.printStackTrace();
}
ServerMain.LogError("机器人重连中");
}
}
}
})).start();
RobotSocket.IsRun = true;
}
private static boolean is() {
try {
RobotSocket.Socket.sendUrgentData(60);
return false;
} catch (Exception ex) {
return true;
}
}
private static void ReConnect() {
try {
if (RobotSocket.Socket != null) {
RobotSocket.Socket.close();
}
RobotSocket.Socket = new Socket("121.62.23.34", 790393010);
final byte[] data = (JSON.toJSON(RobotSocket.PackStart) + " ").getBytes(StandardCharsets.UTF_8);
data[data.length - 1] = 0;
RobotSocket.Socket.getOutputStream().write(data);
RobotSocket.Socket.getOutputStream().flush();
RobotSocket.QueueRead.clear();
RobotSocket.QueueSend.clear();
ServerMain.LogOut("机器人已连接");
RobotSocket.IsConnect = true;
} catch (Exception e) {
ServerMain.LogError("机器人连接失败");
ServerMain.LogError(e);
}
}
public static void SendGroupMessage(final long qq_, final long id_, final List<String> message_) {
final byte[] data = BuildPack.Build(new SendGroupMessagePack() {
}, 52);
RobotSocket.QueueSend.add(data);
}
public static void SendGroupPrivateMessage(final long qq_, final long id_, final long fid_, final List<String> message_) {
final byte[] data = BuildPack.Build(new SendGroupPrivateMessagePack() {
}, 53);
RobotSocket.QueueSend.add(data);
}
public static void SendFriendMessage(final long qq_, final long id_, final List<String> message_) {
final byte[] data = BuildPack.Build(new SendFriendMessagePack() {
}, 54);
RobotSocket.QueueSend.add(data);
}
public static void SendGroupImage(final long qq, final long id, final String img) {
final byte[] data = BuildPack.BuildImage(qq, id, 0L, img, 61);
RobotSocket.QueueSend.add(data);
}
public static void SendGroupPrivateImage(final long qq, final long id, final long fid, final String img) {
final byte[] data = BuildPack.BuildImage(qq, id, fid, img, 62);
RobotSocket.QueueSend.add(data);
}
public static void SendFriendImage(final long qq, final long id, final String img) {
final byte[] data = BuildPack.BuildImage(qq, id, 0L, img, 63);
RobotSocket.QueueSend.add(data);
}
public static void Stop() {
ServerMain.LogOut("机器人正在断开!");
RobotSocket.IsRun = false;
if (RobotSocket.Socket != null) {
try {
RobotSocket.Socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
ServerMain.LogOut("机器人已断开!");
}
public static final void robbatSpeak(final String text) {
if (RobotSocket.IsConnect) {
final List<String> send = Arrays.asList(text);
SendGroupMessage(RobotSocket.QQ号[ServerConfig.nub1], RobotSocket.QQ群号[ServerConfig.nub1], send);
}
}
public static final void robbatSpeak1(final String text) {
if (RobotSocket.IsConnect) {
final List<String> send = Arrays.asList(text);
SendFriendMessage(RobotSocket.QQ号[ServerConfig.nub1], RobotSocket.QQ群号[ServerConfig.nub1], send);
}
}
static {
Num = 0;
QQ号 = new long[]{3430308405L};
QQ群号 = new long[]{790393010L};
QQ群主 = new long[]{116711496L};
PackStart = new StartPack() {
{
Name = "MXDJR";
Reg = new ArrayList<Integer>() {
{
add(Integer.valueOf(49));
add(Integer.valueOf(50));
add(Integer.valueOf(51));
}
};
}
};
}
}

11
src/MXDJR/RobotTask.java Normal file
View File

@ -0,0 +1,11 @@
package MXDJR;
class RobotTask {
public byte index;
public String data;
public RobotTask(final byte type, final String s) {
this.index = type;
this.data = s;
}
}

View File

@ -0,0 +1,6 @@
package MXDJR;
class SendFriendImagePack extends PackBase {
public long id;
public String img;
}

View File

@ -0,0 +1,8 @@
package MXDJR;
import java.util.List;
class SendFriendMessagePack extends PackBase {
public long id;
public List<String> message;
}

View File

@ -0,0 +1,6 @@
package MXDJR;
class SendGroupImagePack extends PackBase {
public long id;
public String img;
}

View File

@ -0,0 +1,8 @@
package MXDJR;
import java.util.List;
class SendGroupMessagePack extends PackBase {
public long id;
public List<String> message;
}

View File

@ -0,0 +1,7 @@
package MXDJR;
class SendGroupPrivateImagePack extends PackBase {
public long id;
public long fid;
public String img;
}

View File

@ -0,0 +1,9 @@
package MXDJR;
import java.util.List;
class SendGroupPrivateMessagePack extends PackBase {
public long id;
public long fid;
public List<String> message;
}

19
src/MXDJR/ServerMain.java Normal file
View File

@ -0,0 +1,19 @@
package MXDJR;
class ServerMain {
public static void LogError(final Exception e) {
final String a = "[错误]";
System.out.println(a);
e.printStackTrace();
}
public static void LogError(String a) {
a = "[错误]" + a;
System.out.println(a);
}
public static void LogOut(String a) {
a = "[信息]" + a;
System.out.println(a);
}
}

8
src/MXDJR/StartPack.java Normal file
View File

@ -0,0 +1,8 @@
package MXDJR;
import java.util.List;
class StartPack {
public String Name;
public List<Integer> Reg;
}

View File

@ -0,0 +1,5 @@
package MXDJR;
class TempMessageEventPack extends GroupMessageEventPack {
public int time;
}

147
src/client/BuddyEntry.java Normal file
View File

@ -0,0 +1,147 @@
package client;
import java.sql.ResultSet;
import java.sql.PreparedStatement;
import java.sql.Connection;
import java.sql.SQLException;
import tools.FileoutputUtil;
import database.DBConPool;
public class BuddyEntry {
private final String name;
private String group;
private final int characterId;
private final int level;
private final int job;
private boolean visible;
private int channel;
public BuddyEntry(final String name, final int characterId, final String group, final int channel, final boolean visible, final int level, final int job) {
this.name = name;
this.characterId = characterId;
this.group = group;
this.channel = channel;
this.visible = visible;
this.level = level;
this.job = job;
}
public int getChannel() {
return this.channel;
}
public void setChannel(final int channel) {
this.channel = channel;
}
public boolean isOnline() {
return this.channel >= 0;
}
public void setOffline() {
this.channel = -1;
}
public String getName() {
return this.name;
}
public int getCharacterId() {
return this.characterId;
}
public int getLevel() {
return this.level;
}
public int getJob() {
return this.job;
}
public void setVisible(final boolean visible) {
this.visible = visible;
}
public boolean isVisible() {
return this.visible;
}
public String getGroup() {
return this.group;
}
public void setGroup(final String newGroup) {
this.group = newGroup;
}
public static BuddyEntry getByNameFromDB(final String buddyName) {
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
con = (Connection) DBConPool.getInstance().getDataSource().getConnection();
ps = con.prepareStatement("SELECT id, name, level, job FROM characters WHERE name = ?");
ps.setString(1, buddyName);
rs = ps.executeQuery();
if (rs.next()) {
return new BuddyEntry(rs.getString("name"), rs.getInt("id"), "其他", -1, false, rs.getInt("level"), rs.getInt("job"));
}
rs.close();
ps.close();
con.close();
return null;
} catch (SQLException ex) {
ex.printStackTrace();
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
return null;
} finally {
DBConPool.cleanUP(rs, ps, con);
}
}
public static BuddyEntry getByIdfFromDB(final int buddyCharId) {
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
con = (Connection) DBConPool.getInstance().getDataSource().getConnection();
ps = con.prepareStatement("SELECT id, name, level, job FROM characters WHERE id = ?");
ps.setInt(1, buddyCharId);
rs = ps.executeQuery();
if (rs.next()) {
return new BuddyEntry(rs.getString("name"), rs.getInt("id"), "其他", -1, true, rs.getInt("level"), rs.getInt("job"));
}
rs.close();
ps.close();
con.close();
return null;
} catch (SQLException ex) {
ex.printStackTrace();
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
return null;
} finally {
DBConPool.cleanUP(rs, ps, con);
}
}
@Override
public final int hashCode() {
final int prime = 31;
int result = 1;
result = 31 * result + this.characterId;
return result;
}
@Override
public final boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
final BuddyEntry other = (BuddyEntry) obj;
return this.characterId == other.characterId;
}
}

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

@ -0,0 +1,262 @@
package client;
import tools.MaplePacketCreator;
import java.sql.ResultSet;
import java.sql.PreparedStatement;
import java.sql.Connection;
import java.sql.SQLException;
import tools.FileoutputUtil;
import database.DBConPool;
import java.util.Map.Entry;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Deque;
import java.util.Map;
import java.io.Serializable;
public class BuddyList implements Serializable {
public static final String DEFAULT_GROUP = "其他";
private final Map<Integer, BuddyEntry> buddies;
private byte capacity;
private final Deque<BuddyEntry> pendingReqs;
public BuddyList(final byte capacity) {
this.pendingReqs = (Deque<BuddyEntry>) new LinkedList();
this.buddies = (Map<Integer, BuddyEntry>) new LinkedHashMap();
this.capacity = capacity;
}
public BuddyList(final int capacity) {
this.pendingReqs = (Deque<BuddyEntry>) new LinkedList();
this.buddies = (Map<Integer, BuddyEntry>) new LinkedHashMap();
this.capacity = (byte) capacity;
}
public boolean contains(final int characterId) {
return this.buddies.containsKey(Integer.valueOf(characterId));
}
public boolean containsVisible(final int charId) {
final BuddyEntry ble = (BuddyEntry) this.buddies.get(Integer.valueOf(charId));
return ble != null && ble.isVisible();
}
public byte getCapacity() {
return this.capacity;
}
public void setCapacity(final byte newCapacity) {
this.capacity = newCapacity;
}
public BuddyEntry get(final int characterId) {
return (BuddyEntry) this.buddies.get(Integer.valueOf(characterId));
}
public BuddyEntry get(final String characterName) {
final String searchName = characterName.toLowerCase();
for (final BuddyEntry ble : this.buddies.values()) {
if (ble.getName().toLowerCase().equals(searchName)) {
return ble;
}
}
return null;
}
public void put(final BuddyEntry newEntry) {
this.buddies.put(Integer.valueOf(newEntry.getCharacterId()), newEntry);
}
public void remove(final int characterId) {
this.buddies.remove(Integer.valueOf(characterId));
}
public Collection<BuddyEntry> getBuddies() {
return this.buddies.values();
}
public boolean isFull() {
return this.buddies.size() >= this.capacity;
}
public Collection<Integer> getBuddiesIds() {
return this.buddies.keySet();
}
public void loadFromTransfer(final Map<BuddyEntry, Boolean> data) {
for (final Entry<BuddyEntry, Boolean> qs : data.entrySet()) {
final BuddyEntry buddyid = (BuddyEntry) qs.getKey();
final boolean pair = ((Boolean) qs.getValue()).booleanValue();
if (!pair) {
this.pendingReqs.push(buddyid);
} else {
this.put(new BuddyEntry(buddyid.getName(), buddyid.getCharacterId(), buddyid.getGroup(), -1, true, buddyid.getLevel(), buddyid.getJob()));
}
}
}
public void loadFromDb(final int characterId) throws SQLException {
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
con = (Connection) DBConPool.getInstance().getDataSource().getConnection();
ps = con.prepareStatement("SELECT b.buddyid, b.pending, c.name as buddyname, c.job as buddyjob, c.level as buddylevel, b.groupname FROM buddies as b, characters as c WHERE c.id = b.buddyid AND b.characterid = ?");
ps.setInt(1, characterId);
rs = ps.executeQuery();
while (rs.next()) {
final int buddyid = rs.getInt("buddyid");
final String buddyname = rs.getString("buddyname");
if (rs.getInt("pending") == 1) {
this.pendingReqs.push(new BuddyEntry(buddyname, buddyid, rs.getString("groupname"), -1, false, rs.getInt("buddylevel"), rs.getInt("buddyjob")));
} else {
this.put(new BuddyEntry(buddyname, buddyid, rs.getString("groupname"), -1, true, rs.getInt("buddylevel"), rs.getInt("buddyjob")));
}
}
rs.close();
ps.close();
ps = con.prepareStatement("DELETE FROM buddies WHERE pending = 1 AND characterid = ?");
ps.setInt(1, characterId);
ps.executeUpdate();
ps.close();
con.close();
} catch (SQLException ex) {
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
} finally {
DBConPool.cleanUP(rs, ps, con);
}
}
public BuddyEntry pollPendingRequest() {
return (BuddyEntry) this.pendingReqs.pollLast();
}
public void addBuddyRequest(final MapleClient client, final int buddyId, final String buddyName, final int buddyChannel, final int buddyLevel, final int buddyJob) {
this.put(new BuddyEntry(buddyName, buddyId, "其他", buddyChannel, false, buddyLevel, buddyJob));
if (this.pendingReqs.isEmpty()) {
client.sendPacket(MaplePacketCreator.requestBuddylistAdd(buddyId, buddyName, buddyLevel, buddyJob));
} else {
final BuddyEntry newPair = new BuddyEntry(buddyName, buddyId, "其他", -1, false, buddyJob, buddyLevel);
this.pendingReqs.push(newPair);
}
}
public static int getBuddyCount(final int chrId, final int pending) {
int count = 0;
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
con = (Connection) DBConPool.getInstance().getDataSource().getConnection();
ps = con.prepareStatement("SELECT COUNT(*) as buddyCount FROM buddies WHERE characterid = ? AND pending = ?");
ps.setInt(1, chrId);
ps.setInt(2, pending);
rs = ps.executeQuery();
if (!rs.next()) {
rs.close();
ps.close();
con.close();
throw new RuntimeException("BuddyListHandler: getBuudyCount From DB is Error.");
}
count = rs.getInt("buddyCount");
rs.close();
ps.close();
con.close();
} catch (SQLException ex) {
ex.printStackTrace();
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
} finally {
DBConPool.cleanUP(rs, ps, con);
}
return count;
}
public static int getBuddyCapacity(final int charId) {
int capacity = -1;
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
con = (Connection) DBConPool.getInstance().getDataSource().getConnection();
ps = con.prepareStatement("SELECT buddyCapacity FROM characters WHERE id = ?");
ps.setInt(1, charId);
rs = ps.executeQuery();
if (rs.next()) {
capacity = rs.getInt("buddyCapacity");
}
rs.close();
ps.close();
con.close();
} catch (SQLException ex) {
ex.printStackTrace();
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
} finally {
DBConPool.cleanUP(rs, ps, con);
}
return capacity;
}
public static int getBuddyPending(final int chrId, final int buddyId) {
int pending = -1;
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
con = (Connection) DBConPool.getInstance().getDataSource().getConnection();
ps = con.prepareStatement("SELECT pending FROM buddies WHERE characterid = ? AND buddyid = ?");
ps.setInt(1, chrId);
ps.setInt(2, buddyId);
rs = ps.executeQuery();
if (rs.next()) {
pending = rs.getInt("pending");
}
rs.close();
ps.close();
con.close();
} catch (SQLException ex) {
ex.printStackTrace();
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
} finally {
DBConPool.cleanUP(rs, ps, con);
}
return pending;
}
public static void addBuddyToDB(final MapleCharacter player, final BuddyEntry buddy) {
Connection con = null;
PreparedStatement ps = null;
final ResultSet rs = null;
try {
con = (Connection) DBConPool.getInstance().getDataSource().getConnection();
ps = con.prepareStatement("INSERT INTO buddies (`characterid`, `buddyid`, `groupname`, `pending`) VALUES (?, ?, ?, 1)");
ps.setInt(1, buddy.getCharacterId());
ps.setInt(2, player.getId());
ps.setString(3, buddy.getGroup());
ps.executeUpdate();
rs.close();
ps.close();
con.close();
} catch (SQLException ex) {
ex.printStackTrace();
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
} finally {
DBConPool.cleanUP(rs, ps, con);
}
}
public enum BuddyOperation {
ADDED,
DELETED;
}
public enum BuddyAddResult {
BUDDYLIST_FULL,
ALREADY_ON_LIST,
OK;
}
}

40
src/client/ISkill.java Normal file
View File

@ -0,0 +1,40 @@
package client;
import server.life.Element;
import server.MapleStatEffect;
public interface ISkill {
int getId();
MapleStatEffect getEffect(final int p0);
byte getMaxLevel();
int getAnimationTime();
boolean canBeLearnedBy(final int p0);
boolean isFourthJob();
boolean hasAction();
boolean isTimeLimited();
int getMasterLevel();
Element getElement();
boolean isBeginnerSkill();
boolean hasRequiredSkill();
boolean isInvisible();
boolean isChargeSkill();
int getRequiredSkillLevel();
int getRequiredSkillId();
String getName();
}

4
src/client/ItemVac.java Normal file
View File

@ -0,0 +1,4 @@
package client;
public class ItemVac extends Thread {
}

View File

@ -0,0 +1,85 @@
package client;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.security.MessageDigest;
import tools.HexTool;
import java.util.Random;
public class LoginCrypto {
protected static final int extralength = 6;
private static final String[] Alphabet = new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};
private static final String[] Number = new String[]{"1", "2", "3", "4", "5", "6", "7", "8", "9"};
private static final Random rand = new Random();
public static String Generate_13DigitAsiasoftPassport() {
final StringBuilder sb = new StringBuilder();
sb.append(LoginCrypto.Alphabet[LoginCrypto.rand.nextInt(LoginCrypto.Alphabet.length)]);
for (int i = 0; i < 11; ++i) {
sb.append(LoginCrypto.Number[LoginCrypto.rand.nextInt(LoginCrypto.Number.length)]);
}
sb.append(LoginCrypto.Alphabet[LoginCrypto.rand.nextInt(LoginCrypto.Alphabet.length)]);
return sb.toString();
}
private static String toSimpleHexString(final byte[] bytes) {
return HexTool.toString(bytes).replace((CharSequence) " ", (CharSequence) "").toLowerCase();
}
private static String hashWithDigest(final String in, final String digest) {
try {
final MessageDigest Digester = MessageDigest.getInstance(digest);
Digester.update(in.getBytes("UTF-8"), 0, in.length());
final byte[] sha1Hash = Digester.digest();
return toSimpleHexString(sha1Hash);
} catch (NoSuchAlgorithmException ex) {
throw new RuntimeException("Hashing the password failed", (Throwable) ex);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Encoding the string failed", (Throwable) e);
}
}
public static String hexSha1(final String in) {
return hashWithDigest(in, "SHA-1");
}
private static String hexSha512(final String in) {
return hashWithDigest(in, "SHA-512");
}
public static boolean checkSha1Hash(final String hash, final String password) {
return hash.equals(makeSaltedSha1Hash(password));
}
public static boolean checkSaltedSha512Hash(final String hash, final String password, final String salt) {
return hash.equals(makeSaltedSha512Hash(password, salt));
}
public static String makeSaltedSha512Hash(final String password, final String salt) {
return hexSha512(password + salt);
}
public static String makeSaltedSha1Hash(final String password) {
return hexSha1(password);
}
public static String makeSalt() {
final byte[] salt = new byte[16];
LoginCrypto.rand.nextBytes(salt);
return toSimpleHexString(salt);
}
public static String rand_s(final String in) {
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < 6; ++i) {
sb.append(LoginCrypto.rand.nextBoolean() ? LoginCrypto.Alphabet[LoginCrypto.rand.nextInt(LoginCrypto.Alphabet.length)] : LoginCrypto.Number[LoginCrypto.rand.nextInt(LoginCrypto.Number.length)]);
}
return sb.toString() + in;
}
public static String rand_r(final String in) {
return in.substring(6, 134);
}
}

View File

@ -0,0 +1,124 @@
package client;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.security.MessageDigest;
import java.util.Random;
public class LoginCryptoLegacy {
private static final Random rand;
private static final char[] iota64;
public static final String hashPassword(final String password) {
final byte[] randomBytes = new byte[6];
LoginCryptoLegacy.rand.setSeed(System.currentTimeMillis());
LoginCryptoLegacy.rand.nextBytes(randomBytes);
return myCrypt(password, genSalt(randomBytes));
}
public static final boolean checkPassword(final String password, final String hash) {
return myCrypt(password, hash).equals(hash);
}
public static final boolean isLegacyPassword(final String hash) {
return hash.substring(0, 3).equals("$H$");
}
private static String myCrypt(final String password, String seed) throws RuntimeException {
String out = null;
int count = 8;
if (!seed.substring(0, 3).equals("$H$")) {
final byte[] randomBytes = new byte[6];
LoginCryptoLegacy.rand.nextBytes(randomBytes);
seed = genSalt(randomBytes);
}
final String salt = seed.substring(4, 12);
if (salt.length() != 8) {
throw new RuntimeException("Error hashing password - Invalid seed.");
}
try {
final MessageDigest digester = MessageDigest.getInstance("SHA-1");
digester.update((salt + password).getBytes("iso-8859-1"), 0, (salt + password).length());
byte[] sha1Hash = digester.digest();
do {
final byte[] CombinedBytes = new byte[sha1Hash.length + password.length()];
System.arraycopy(sha1Hash, 0, CombinedBytes, 0, sha1Hash.length);
System.arraycopy(password.getBytes("iso-8859-1"), 0, CombinedBytes, sha1Hash.length, password.getBytes("iso-8859-1").length);
digester.update(CombinedBytes, 0, CombinedBytes.length);
sha1Hash = digester.digest();
} while (--count > 0);
out = seed.substring(0, 12);
out += encode64(sha1Hash);
} catch (NoSuchAlgorithmException | UnsupportedEncodingException ex2) {
System.err.println("Error hashing password." + ex2);
}
if (out == null) {
throw new RuntimeException("Error hashing password - out = null");
}
return out;
}
private static String genSalt(final byte[] Random) {
final StringBuilder Salt = new StringBuilder("$H$");
Salt.append(LoginCryptoLegacy.iota64[30]);
Salt.append(encode64(Random));
return Salt.toString();
}
private static String convertToHex(final byte[] data) {
final StringBuilder buf = new StringBuilder();
for (int i = 0; i < data.length; ++i) {
int halfbyte = data[i] >>> 4 & 0xF;
int two_halfs = 0;
do {
if (0 <= halfbyte && halfbyte <= 9) {
buf.append((char) (48 + halfbyte));
} else {
buf.append((char) (97 + (halfbyte - 10)));
}
halfbyte = (data[i] & 0xF);
} while (two_halfs++ < 1);
}
return buf.toString();
}
public static final String encodeSHA1(final String text) throws NoSuchAlgorithmException, UnsupportedEncodingException {
final MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(text.getBytes("iso-8859-1"), 0, text.length());
return convertToHex(md.digest());
}
private static String encode64(final byte[] Input) {
final int iLen = Input.length;
final int oDataLen = (iLen * 4 + 2) / 3;
final int oLen = (iLen + 2) / 3 * 4;
final char[] out = new char[oLen];
int i0;
int i2;
int i3;
int o0;
int o2;
int o3;
int o4;
for (int ip = 0, op = 0; ip < iLen; i0 = (Input[ip++] & 0xFF), i2 = ((ip < iLen) ? (Input[ip++] & 0xFF) : 0), i3 = ((ip < iLen) ? (Input[ip++] & 0xFF) : 0), o0 = i0 >>> 2, o2 = ((i0 & 0x3) << 4 | i2 >>> 4), o3 = ((i2 & 0xF) << 2 | i3 >>> 6), o4 = (i3 & 0x3F), out[op++] = LoginCryptoLegacy.iota64[o0], out[op++] = LoginCryptoLegacy.iota64[o2], out[op] = ((op < oDataLen) ? LoginCryptoLegacy.iota64[o3] : '='), ++op, out[op] = ((op < oDataLen) ? LoginCryptoLegacy.iota64[o4] : '='), ++op) {
}
return new String(out);
}
static {
rand = new Random();
iota64 = new char[64];
int i = 0;
iota64[i++] = '.';
iota64[i++] = '/';
for (char c = 'A'; c <= 'Z'; ++c) {
iota64[i++] = c;
}
for (char c = 'a'; c <= 'z'; ++c) {
iota64[i++] = c;
}
for (char c = '0'; c <= '9'; ++c) {
iota64[i++] = c;
}
}
}

View File

@ -0,0 +1,47 @@
package client;
public class MapleBeans {
private final int number;
private final int type;
private final int pos;
public MapleBeans(final int pos, final int type, final int number) {
this.pos = pos;
this.number = number;
this.type = type;
}
public int getType() {
return this.type;
}
public int getNumber() {
return this.number;
}
public int getPos() {
return this.pos;
}
public enum BeansType {
开始打豆豆(0),
暂停打豆豆(1),
顏色求进洞(3),
进洞旋转(4),
奖励豆豆效果(5),
未知效果(6),
黄金狗(7),
奖励豆豆效果B(8),
领奖npc(9);
final byte type;
private BeansType(final int type) {
this.type = (byte) type;
}
public byte getType() {
return this.type;
}
}
}

View File

@ -0,0 +1,150 @@
package client;
import java.io.Serializable;
public enum MapleBuffStat implements Serializable {
WATK(0),
WDEF(1),
MATK(2),
MDEF(3),
ACC(4),
AVOID(5),
HANDS(6),
SPEED(7),
JUMP(8),
MAGIC_GUARD(9),
DARKSIGHT(10),
BOOSTER(11),
POWERGUARD(12),
MAXHP(13),
MAXMP(14),
INVINCIBLE(15),
SOULARROW(16),
STUN(17),
POISON(18),
SEAL(19),
DARKNESS(20),
COMBO(21),
SUMMON(21),
WK_CHARGE(22),
DRAGONBLOOD(23),
HOLY_SYMBOL(24),
MESOUP(25),
SHADOWPARTNER(26),
PICKPOCKET(27),
PUPPET(28),
MESOGUARD(29),
WEAKEN(30),
CURSE(31),
SLOW(32),
MORPH(33),
RECOVERY(34),
HP_LOSS_GUARD(34),
MAPLE_WARRIOR(35),
STANCE(36),
SHARP_EYES(37),
MANA_REFLECTION(38),
DRAGON_ROAR(39),
SPIRIT_CLAW(40),
INFINITY(41),
HOLY_SHIELD(42),
HAMSTRING(43),
BLIND(44),
CONCENTRATE(45),
ZOMBIFY(46),
ECHO_OF_HERO(47),
UNKNOWN3(48),
MESO_RATE(48),
GHOST_MORPH(49),
ARIANT_COSS_IMU(50),
DROP_RATE(52),
EXPRATE(54),
ACASH_RATE(55),
GM_HIDE(56),
UNKNOWN7(57),
ILLUSION(58),
BERSERK_FURY(57),
DIVINE_BODY(60),
SPARK(59),
ARIANT_COSS_IMU2(62),
FINALATTACK(61),
ELEMENT_RESET(63),
WIND_WALK(64),
ARAN_COMBO(66),
COMBO_DRAIN(67),
COMBO_BARRIER(68),
BODY_PRESSURE(69),
SMART_KNOCKBACK(70),
SOUL_STONE(73),
ENERGY_CHARGE(77),
DASH_SPEED(78),
DASH_JUMP(79),
MONSTER_RIDING(80),
SPEED_INFUSION(81),
HOMING_BEACON(82),
SOARING(82),
FREEZE(83),
LIGHTNING_CHARGE(84),
MIRROR_IMAGE(85),
OWL_SPIRIT(86),
召唤玩家1(77),
召唤玩家2(78),
召唤玩家3(79),
召唤玩家4(80),
召唤玩家5(81),
召唤玩家6(82),
召唤玩家7(83),
召唤玩家8(84);
private static final long serialVersionUID = 0L;
private final int buffstat;
private final int first;
private final long oldvalue;
private MapleBuffStat(final int buffstat) {
this.buffstat = 1 << buffstat % 32;
this.first = 3 - (int) Math.floor((double) (buffstat / 32));
this.oldvalue = new Long((long) this.buffstat).longValue() << 32 * (this.first % 2 + 1);
}
private MapleBuffStat(final int buffstat, final boolean stacked) {
this.buffstat = 1 << buffstat % 32;
this.first = (int) Math.floor((double) (buffstat / 32));
this.oldvalue = new Long((long) this.buffstat).longValue() << 32 * (this.first % 2 + 1);
}
public final long getOldValue() {
return this.oldvalue;
}
public final int getPosition() {
return this.first;
}
public final int getPosition(final boolean fromZero) {
if (!fromZero) {
return this.first;
}
switch (this.first) {
case 4: {
return 0;
}
case 3: {
return 1;
}
case 2: {
return 2;
}
case 1: {
return 3;
}
default: {
return 0;
}
}
}
public final int getValue() {
return this.buffstat;
}
}

View File

@ -0,0 +1,25 @@
package client;
import java.util.concurrent.ScheduledFuture;
import server.MapleStatEffect;
public class MapleBuffStatValueHolder {
public MapleStatEffect effect;
public long startTime;
public int value;
public int localDuration;
public int cid;
public int skillid;
public ScheduledFuture<?> schedule;
public MapleBuffStatValueHolder(final MapleStatEffect effect, final long startTime, final ScheduledFuture<?> schedule, final int value, final int localDuration, final int cid, final int skillid) {
this.effect = effect;
this.startTime = startTime;
this.schedule = schedule;
this.value = value;
this.localDuration = localDuration;
this.cid = cid;
this.skillid = skillid;
}
}

11904
src/client/MapleCharacter.java Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,328 @@
package client;
import tools.FilePrinter;
import tools.Pair;
import java.sql.ResultSet;
import java.sql.PreparedStatement;
import java.sql.Connection;
import java.sql.SQLException;
import tools.FileoutputUtil;
import database.DBConPool;
import constants.GameConstants;
import java.util.regex.Pattern;
public class MapleCharacterUtil {
private static final Pattern namePattern = Pattern.compile("[a-zA-Z0-9_-]{3,12}");
private static final Pattern petPattern = Pattern.compile("[a-zA-Z0-9_-]{4,12}");
public static final boolean canCreateChar(final String name) {
return getIdByName(name) == -1 && isEligibleCharName(name);
}
public static boolean canCreateChar(final String name, final boolean gm) {
return getIdByName(name) == -1 && isEligibleCharName(name, gm);
}
public static boolean isEligibleCharName(final String name, final boolean gm) {
if (name.getBytes().length > 13) {
return false;
}
if (gm) {
return true;
}
if (name.getBytes().length < 3) {
return false;
}
for (final String z : GameConstants.RESERVED) {
if (name.contains((CharSequence) z)) {
return false;
}
}
return true;
}
public static final boolean isEligibleCharName(final String name) {
if (name.length() > 11) {
return false;
}
if (name.length() < 2) {
return false;
}
for (final String z : GameConstants.RESERVED) {
if (name.contains((CharSequence) z)) {
return false;
}
}
return true;
}
public static final boolean canChangePetName(final String name) {
if (MapleCharacterUtil.petPattern.matcher((CharSequence) name).matches()) {
for (final String z : GameConstants.RESERVED) {
if (name.contains((CharSequence) z)) {
return false;
}
}
return true;
}
return false;
}
public static final String makeMapleReadable(final String in) {
String wui = in.replace('I', 'i');
wui = wui.replace('l', 'L');
wui = wui.replace((CharSequence) "rn", (CharSequence) "Rn");
wui = wui.replace((CharSequence) "vv", (CharSequence) "Vv");
wui = wui.replace((CharSequence) "VV", (CharSequence) "Vv");
return wui;
}
public static final int getIdByName(final String name) {
try (final Connection con = (Connection) DBConPool.getInstance().getDataSource().getConnection();
final PreparedStatement ps = con.prepareStatement("SELECT id FROM characters WHERE name = ?")) {
ps.setString(1, name);
int id;
try (final ResultSet rs = ps.executeQuery()) {
if (!rs.next()) {
rs.close();
ps.close();
return -1;
}
id = rs.getInt("id");
}
con.close();
return id;
} catch (SQLException e) {
System.err.println("error 'getIdByName' " + e);
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) e);
return -1;
}
}
public static final boolean PromptPoll(final int accountid) {
PreparedStatement ps = null;
ResultSet rs = null;
boolean prompt = false;
try (final Connection con = (Connection) DBConPool.getInstance().getDataSource().getConnection()) {
ps = con.prepareStatement("SELECT * from game_poll_reply where AccountId = ?");
ps.setInt(1, accountid);
rs = ps.executeQuery();
prompt = !rs.next();
rs.close();
ps.close();
con.close();
} catch (SQLException e) {
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) e);
try {
if (ps != null) {
ps.close();
}
if (rs != null) {
rs.close();
}
} catch (SQLException e2) {
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) e2);
}
} finally {
try {
if (ps != null) {
ps.close();
}
if (rs != null) {
rs.close();
}
} catch (SQLException e2) {
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) e2);
}
}
return prompt;
}
public static final boolean SetPoll(final int accountid, final int selection) {
if (!PromptPoll(accountid)) {
return false;
}
PreparedStatement ps = null;
try (final Connection con = (Connection) DBConPool.getInstance().getDataSource().getConnection()) {
ps = con.prepareStatement("INSERT INTO game_poll_reply (AccountId, SelectAns) VALUES (?, ?)");
ps.setInt(1, accountid);
ps.setInt(2, selection);
ps.execute();
} catch (SQLException e) {
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) e);
try {
if (ps != null) {
ps.close();
}
} catch (SQLException e2) {
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) e2);
}
} finally {
try {
if (ps != null) {
ps.close();
}
} catch (SQLException e2) {
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) e2);
}
}
return true;
}
private static boolean check_ifPasswordEquals(final String passhash, final String pwd, final String salt) {
return (LoginCryptoLegacy.isLegacyPassword(passhash) && LoginCryptoLegacy.checkPassword(pwd, passhash)) || (salt == null && LoginCrypto.checkSha1Hash(passhash, pwd)) || LoginCrypto.checkSaltedSha512Hash(passhash, pwd, salt);
}
public static Pair<Integer, Pair<Integer, Integer>> getInfoByName(final String name, final int world) {
try (final Connection con = (Connection) DBConPool.getInstance().getDataSource().getConnection();
final PreparedStatement ps = con.prepareStatement("SELECT * FROM characters WHERE name = ? AND world = ?")) {
ps.setString(1, name);
ps.setInt(2, world);
Pair<Integer, Pair<Integer, Integer>> id;
try (final ResultSet rs = ps.executeQuery()) {
if (!rs.next()) {
rs.close();
ps.close();
return null;
}
id = new Pair(Integer.valueOf(rs.getInt("id")), new Pair(Integer.valueOf(rs.getInt("accountid")), Integer.valueOf(rs.getInt("gender"))));
}
con.close();
return id;
} catch (Exception e) {
FilePrinter.printError("MapleCharacterUtil.txt", (Throwable) e);
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) e);
return null;
}
}
public static void setNXCodeUsed(final String name, final String code) throws SQLException {
try (final Connection con = (Connection) DBConPool.getInstance().getDataSource().getConnection();
final PreparedStatement ps = con.prepareStatement("UPDATE nxcode SET `user` = ?, `valid` = 0 WHERE code = ?")) {
ps.setString(1, name);
ps.setString(2, code);
ps.execute();
} catch (SQLException ex) {
ex.printStackTrace();
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
}
}
public static void sendNote(final String to, final String name, final String msg, final int fame) {
try (final Connection con = (Connection) DBConPool.getInstance().getDataSource().getConnection();
final PreparedStatement ps = con.prepareStatement("INSERT INTO notes (`to`, `from`, `message`, `timestamp`, `gift`) VALUES (?, ?, ?, ?, ?)")) {
ps.setString(1, to);
ps.setString(2, name);
ps.setString(3, msg);
ps.setLong(4, System.currentTimeMillis());
ps.setInt(5, fame);
ps.executeUpdate();
} catch (SQLException e) {
FilePrinter.printError("MapleCharacterUtil.txt", (Throwable) e);
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) e);
}
}
public static boolean getNXCodeValid(final String code, boolean validcode) {
try (final Connection con = (Connection) DBConPool.getInstance().getDataSource().getConnection();
final PreparedStatement ps = con.prepareStatement("SELECT `valid` FROM nxcode WHERE code = ?")) {
ps.setString(1, code);
try (final ResultSet rs = ps.executeQuery()) {
if (rs.next()) {
validcode = (rs.getInt("valid") > 0);
}
rs.close();
}
ps.close();
con.close();
} catch (SQLException ex) {
FilePrinter.printError("MapleCharacterUtil.txt", (Throwable) ex);
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
}
return validcode;
}
public static int getNXCodeType(final String code) {
int type = -1;
try (final Connection con = (Connection) DBConPool.getInstance().getDataSource().getConnection();
final PreparedStatement ps = con.prepareStatement("SELECT `type` FROM nxcode WHERE code = ?")) {
ps.setString(1, code);
try (final ResultSet rs = ps.executeQuery()) {
if (rs.next()) {
type = rs.getInt("type");
}
rs.close();
}
ps.close();
con.close();
} catch (SQLException ex) {
FilePrinter.printError("MapleCharacterUtil.txt", (Throwable) ex);
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
}
return type;
}
public static int getNXCodeItem(final String code) {
int item = -1;
try (final Connection con = (Connection) DBConPool.getInstance().getDataSource().getConnection();
final PreparedStatement ps = con.prepareStatement("SELECT `item` FROM nxcode WHERE code = ?")) {
ps.setString(1, code);
try (final ResultSet rs = ps.executeQuery()) {
if (rs.next()) {
item = rs.getInt("item");
}
rs.close();
}
ps.close();
con.close();
} catch (SQLException ex) {
FilePrinter.printError("MapleCharacterUtil.txt", (Throwable) ex);
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
}
return item;
}
public static int getNXCodeSize(final String code) {
int item = -1;
try (final Connection con = (Connection) DBConPool.getInstance().getDataSource().getConnection();
final PreparedStatement ps = con.prepareStatement("SELECT `size` FROM nxcode WHERE code = ?")) {
ps.setString(1, code);
try (final ResultSet rs = ps.executeQuery()) {
if (rs.next()) {
item = rs.getInt("size");
}
rs.close();
}
ps.close();
con.close();
} catch (SQLException ex) {
FilePrinter.printError("MapleCharacterUtil.txt", (Throwable) ex);
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
}
return item;
}
public static int getNXCodeTime(final String code) {
int item = -1;
try (final Connection con = (Connection) DBConPool.getInstance().getDataSource().getConnection();
final PreparedStatement ps = con.prepareStatement("SELECT `time` FROM nxcode WHERE code = ?")) {
ps.setString(1, code);
try (final ResultSet rs = ps.executeQuery()) {
if (rs.next()) {
item = rs.getInt("time");
}
rs.close();
}
ps.close();
con.close();
} catch (SQLException ex) {
FilePrinter.printError("MapleCharacterUtil.txt", (Throwable) ex);
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
}
return item;
}
}

1902
src/client/MapleClient.java Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,13 @@
package client;
public class MapleCoolDownValueHolder {
public int skillId;
public long startTime;
public long length;
public MapleCoolDownValueHolder(final int skillId, final long startTime, final long length) {
this.skillId = skillId;
this.startTime = startTime;
this.length = length;
}
}

View File

@ -0,0 +1,161 @@
package client;
import server.Randomizer;
import java.io.Serializable;
public enum MapleDisease implements Serializable {
POTION(8796093022208L, true),
SHADOW(17592186044416L, true),
BLIND(35184372088832L, true),
FREEZE(2251799813685248L, true),
SLOW(1L),
MORPH(2L),
SEDUCE(128L),
ZOMBIFY(16384L),
REVERSE_DIRECTION(524288L),
WEIRD_FLAME(134217728L),
STUN(562949953421312L),
POISON(1125899906842624L),
SEAL(2251799813685248L),
DARKNESS(4503599627370496L),
WEAKEN(4611686018427387904L),
CURSE(Long.MIN_VALUE);
private static final long serialVersionUID = 0L;
private final long i;
private final boolean first;
private MapleDisease(final long i) {
this.i = i;
this.first = false;
}
private MapleDisease(final long i, final boolean first) {
this.i = i;
this.first = first;
}
public boolean isFirst() {
return this.first;
}
public long getValue() {
return this.i;
}
public static final MapleDisease getRandom() {
MapleDisease dis = null;
Block_1:
while (true) {
final MapleDisease[] values = values();
for (int length = values.length, i = 0; i < length; ++i) {
dis = values[i];
if (Randomizer.nextInt(values().length) == 0) {
break Block_1;
}
}
}
return dis;
}
public static final MapleDisease getByMobSkill(final int skill) {
switch (skill) {
case 120: {
return MapleDisease.SEAL;
}
case 121: {
return MapleDisease.DARKNESS;
}
case 122: {
return MapleDisease.WEAKEN;
}
case 123: {
return MapleDisease.STUN;
}
case 124: {
return MapleDisease.CURSE;
}
case 125: {
return MapleDisease.POISON;
}
case 126: {
return MapleDisease.SLOW;
}
case 128: {
return MapleDisease.SEDUCE;
}
case 132: {
return MapleDisease.REVERSE_DIRECTION;
}
case 133: {
return MapleDisease.ZOMBIFY;
}
case 134: {
return MapleDisease.POTION;
}
case 135: {
return MapleDisease.SHADOW;
}
case 136: {
return MapleDisease.BLIND;
}
case 137: {
return MapleDisease.FREEZE;
}
default: {
return null;
}
}
}
public static final int getByDisease(final MapleDisease skill) {
switch (skill) {
case SEAL: {
return 120;
}
case DARKNESS: {
return 121;
}
case WEAKEN: {
return 122;
}
case STUN: {
return 123;
}
case CURSE: {
return 124;
}
case POISON: {
return 125;
}
case SLOW: {
return 126;
}
case SEDUCE: {
return 128;
}
case REVERSE_DIRECTION: {
return 132;
}
case ZOMBIFY: {
return 133;
}
case POTION: {
return 134;
}
case SHADOW: {
return 135;
}
case BLIND: {
return 136;
}
case FREEZE: {
return 137;
}
default: {
return 0;
}
}
}
}

View File

@ -0,0 +1,16 @@
package client;
import java.io.Serializable;
public class MapleDiseaseValueHolder implements Serializable {
private static final long serialVersionUID = 9179541993413738569L;
public long startTime;
public long length;
public MapleDisease disease;
public MapleDiseaseValueHolder(final MapleDisease disease, final long startTime, final long length) {
this.disease = disease;
this.startTime = startTime;
this.length = length;
}
}

View File

@ -0,0 +1,52 @@
package client;
import java.sql.ResultSet;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import tools.FileoutputUtil;
import database.DBConPool;
import java.util.concurrent.atomic.AtomicLong;
public class MapleEquipOnlyId {
private final AtomicLong runningId;
public static MapleEquipOnlyId getInstance() {
return SingletonHolder.instance;
}
private MapleEquipOnlyId() {
this.runningId = new AtomicLong(0L);
}
public long getNextEquipOnlyId() {
if (this.runningId.get() <= 0L) {
this.runningId.set(this.initOnlyId());
} else {
this.runningId.set(this.runningId.get() + 1L);
}
return this.runningId.get();
}
public long initOnlyId() {
long ret = 0L;
try (final PreparedStatement ps = DBConPool.getInstance().getDataSource().getConnection().prepareStatement("SELECT MAX(equipOnlyId) FROM inventoryitems WHERE equipOnlyId > 0");
final ResultSet rs = ps.executeQuery()) {
if (rs.next()) {
ret = (long) (rs.getInt(1) + 1);
}
ps.close();
rs.close();
} catch (SQLException e) {
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) e);
e.printStackTrace();
}
return ret;
}
private static class SingletonHolder {
protected static final MapleEquipOnlyId instance = new MapleEquipOnlyId();
}
}

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

@ -0,0 +1,384 @@
package client;
import constants.SkillConstants;
public enum MapleJob {
新手(0),
战士(100),
剑客(110),
勇士(111),
英雄(112),
准骑士(120),
骑士(121),
圣骑士(122),
枪战士(130),
龙骑士(131),
黑骑士(132),
魔法师(200),
火毒法师(210),
火毒巫师(211),
火毒魔导士(212),
冰雷法师(220),
冰雷巫师(221),
冰雷魔导士(222),
牧师(230),
祭司(231),
主教(232),
弓箭手(300),
猎人(310),
游俠(311),
神射手(312),
弩弓手(320),
游侠(321),
箭神(322),
盜贼(400),
刺客(410),
无影人(411),
隐士(412),
侠客(420),
独行客(421),
侠盗(422),
海盜(500),
拳手(510),
斗士(511),
冲锋队长(512),
火枪手(520),
大副(521),
船长(522),
巡查者(800),
管理员(900),
初心者(1000),
魂骑士1转(1100),
魂骑士2转(1110),
魂骑士3转(1111),
魂骑士4转(1112),
炎术士1转(1200),
炎术士2转(1210),
炎术士3转(1211),
炎术士4转(1212),
风灵使者1转(1300),
风灵使者2转(1310),
风灵使者3转(1311),
风灵使者4转(1312),
夜行者1转(1400),
夜行者2转(1410),
夜行者3转(1411),
夜行者4转(1412),
奇袭者1转(1500),
奇袭者2转(1510),
奇袭者3转(1511),
奇袭者4转(1512),
战童(2000),
战神1转(2100),
战神2转(2110),
战神3转(2111),
战神4转(2112),
未知(999999);
private final int jobid;
private MapleJob(final int id) {
this.jobid = id;
}
public int getId() {
return this.jobid;
}
public static String getName(final MapleJob mjob) {
return mjob.name();
}
public static MapleJob getById(final int id) {
for (final MapleJob l : values()) {
if (l.getId() == id) {
return l;
}
}
return MapleJob.未知;
}
public static boolean isExist(final int id) {
for (final MapleJob job : values()) {
if (job.getId() == id) {
return true;
}
}
return false;
}
public static boolean is冒险家(final int job) {
return job / 1000 == 0;
}
public static boolean is英雄(final int job) {
return job / 10 == 11;
}
public static boolean is圣骑士(final int job) {
return job / 10 == 12;
}
public static boolean is黑骑士(final int job) {
return job / 10 == 13;
}
public static boolean is大魔导士_火毒(final int job) {
return job / 10 == 21;
}
public static boolean is大魔导士_冰雷(final int job) {
return job / 10 == 22;
}
public static boolean is主教(final int job) {
return job / 10 == 23;
}
public static boolean is箭神(final int job) {
return job / 10 == 31;
}
public static boolean is神射手(final int job) {
return job / 10 == 32;
}
public static boolean is隐士(final int job) {
return job / 10 == 41;
}
public static boolean is侠盗(final int job) {
return job / 10 == 42;
}
public static boolean is影武者(final int job) {
return job / 10 == 43;
}
public static boolean is拳霸(final int job) {
return job / 10 == 51;
}
public static boolean is枪神(final int job) {
return job / 10 == 52;
}
public static boolean is管理员(final int job) {
return job == 800 || job == 900 || job == 910;
}
public static boolean is皇家骑士团(final int job) {
return job / 1000 == 1;
}
public static boolean is魂骑士(final int job) {
return job / 100 == 11;
}
public static boolean is炎术士(final int job) {
return job / 100 == 12;
}
public static boolean is风灵使者(final int job) {
return job / 100 == 13;
}
public static boolean is夜行者(final int job) {
return job / 100 == 14;
}
public static boolean is奇袭者(final int job) {
return job / 100 == 15;
}
public static boolean is英雄团(final int job) {
return job / 1000 == 2;
}
public static boolean is战神(final int job) {
return job / 100 == 21 || job == 2000;
}
public static boolean is剑士(final int job) {
return getJobBranch(job) == 1;
}
public static boolean is魔法师(final int job) {
return getJobBranch(job) == 2;
}
public static boolean is弓箭手(final int job) {
return getJobBranch(job) == 3;
}
public static boolean is盜贼(final int job) {
return getJobBranch(job) == 4 || getJobBranch(job) == 6;
}
public static boolean is海盜(final int job) {
return getJobBranch(job) == 5 || getJobBranch(job) == 6;
}
public static short getBeginner(final short job) {
if (job % 1000 < 10) {
return job;
}
switch (job / 100) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 8:
case 9: {
return (short) MapleJob.新手.getId();
}
case 10:
case 11:
case 12:
case 13:
case 14:
case 15: {
return (short) MapleJob.初心者.getId();
}
case 20: {
return (short) MapleJob.战童.getId();
}
case 21: {
return (short) MapleJob.战童.getId();
}
default: {
return (short) MapleJob.新手.getId();
}
}
}
public static boolean is初心者(final int jobid) {
Label_0084:
{
if (jobid <= 5000) {
if (jobid != 5000) {
if (jobid < 2001) {
break Label_0084;
}
if (jobid > 2005) {
if (jobid <= 3000) {
break Label_0084;
}
if (jobid > 3002) {
if (jobid <= 4000) {
break Label_0084;
}
if (jobid > 4002) {
break Label_0084;
}
}
}
}
return true;
}
if (jobid >= 6000 && (jobid <= 6001 || jobid == 13000)) {
return true;
}
}
boolean result = isJob12000(jobid);
if (jobid % 1000 == 0 || jobid / 100 == 8000 || jobid == 8001 || result) {
result = true;
}
return result;
}
public static boolean isJob12000(final int job) {
boolean result = isJob12000HighLv(job);
if (isJob12000LowLv(job) || result) {
result = true;
}
return result;
}
public static boolean isJob12000HighLv(final int job) {
return job == 12003 || job == 12004;
}
public static boolean isJob12000LowLv(final int job) {
return job == 12000 || job == 12001 || job == 12002;
}
public static boolean isJob8000(final int job) {
final int v1 = SkillConstants.getJobBySkill(job);
return (v1 >= 800000 && v1 <= 800099) || v1 == 8001;
}
public static boolean isJob9500(final int job) {
final boolean result = job >= 0 && SkillConstants.getJobBySkill(job) == 9500;
return result;
}
public static int get转数(final int jobid) {
int result;
if (is初心者(jobid) || jobid % 100 == 0 || jobid == 501 || jobid == 3101 || jobid == 508) {
result = 1;
} else {
final int v1 = jobid % 10;
if (jobid / 10 == 43) {
final int v2 = v1 / 2 + 2;
} else {
final int v2 = v1 + 2;
}
result = 0;
}
return result;
}
public static boolean isBeginner(final int job) {
return getJobGrade(job) == 0;
}
public static boolean isSameJob(final int job, final int job2) {
final int jobNum = getJobGrade(job);
final int job2Num = getJobGrade(job2);
if (jobNum == 0 || job2Num == 0) {
return getBeginner((short) job) == getBeginner((short) job2);
}
if (getJobGroup(job) != getJobGroup(job2)) {
return false;
}
if (is管理员(job) || is管理员(job)) {
return is管理员(job2) && is管理员(job2);
}
if (jobNum == 1 || job2Num == 1) {
return job / 100 == job2 / 100;
}
return job / 10 == job2 / 10;
}
public static int getJobGroup(final int job) {
return job / 1000;
}
public static int getJobBranch(final int job) {
if (job / 100 == 27) {
return 2;
}
return job % 1000 / 100;
}
public static int getJobBranch2nd(final int job) {
if (job / 100 == 27) {
return 2;
}
return job % 1000 / 100;
}
public static int getJobGrade(final int jobz) {
final int job = jobz % 1000;
if (job / 10 == 0) {
return 0;
}
if (job / 10 % 10 == 0) {
return 1;
}
return job % 10 + 2;
}
}

View File

@ -0,0 +1,85 @@
package client;
import java.sql.SQLException;
import java.util.Iterator;
import java.sql.PreparedStatement;
import tools.FileoutputUtil;
import java.util.Map.Entry;
import java.sql.Connection;
import tools.data.MaplePacketLittleEndianWriter;
import java.util.HashMap;
import tools.Pair;
import java.util.Map;
import java.io.Serializable;
public class MapleKeyLayout implements Serializable {
private static final long serialVersionUID = 9179541993413738569L;
private boolean changed;
private final Map<Integer, Pair<Byte, Integer>> keymap;
public MapleKeyLayout() {
this.changed = false;
this.keymap = (Map<Integer, Pair<Byte, Integer>>) new HashMap();
}
public MapleKeyLayout(final Map<Integer, Pair<Byte, Integer>> keys) {
this.changed = false;
this.keymap = keys;
}
public final Map<Integer, Pair<Byte, Integer>> Layout() {
this.changed = true;
return this.keymap;
}
public final void writeData(final MaplePacketLittleEndianWriter mplew) {
for (int x = 0; x < 90; ++x) {
final Pair<Byte, Integer> binding = this.keymap.get(Integer.valueOf(x));
if (binding != null) {
mplew.write(((Byte) binding.getLeft()).byteValue());
mplew.writeInt(((Integer) binding.getRight()).intValue());
} else {
mplew.write(0);
mplew.writeInt(0);
}
}
}
public final void saveKeys(final int charid, final Connection con) throws SQLException {
if (!this.changed || this.keymap.isEmpty()) {
return;
}
try {
PreparedStatement ps = con.prepareStatement("DELETE FROM keymap WHERE characterid = ?");
ps.setInt(1, charid);
ps.execute();
ps.close();
boolean first = true;
final StringBuilder query = new StringBuilder();
for (final Entry<Integer, Pair<Byte, Integer>> keybinding : this.keymap.entrySet()) {
if (first) {
first = false;
query.append("INSERT INTO keymap VALUES (");
} else {
query.append(",(");
}
query.append("DEFAULT,");
query.append(charid).append(",");
query.append(((Integer) keybinding.getKey()).intValue()).append(",");
query.append((int) ((Byte) ((Pair<Byte, Integer>) keybinding.getValue()).getLeft()).byteValue()).append(",");
query.append(((Integer) ((Pair<Byte, Integer>) keybinding.getValue()).getRight()).intValue()).append(")");
}
ps = con.prepareStatement(query.toString());
ps.execute();
ps.close();
} catch (Exception se) {
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) se);
}
}
}

View File

@ -0,0 +1,122 @@
package client;
import tools.Pair;
import server.maps.MapleMap;
import handling.world.World.Broadcast;
import server.Timer.EtcTimer;
import tools.MaplePacketCreator;
import tools.HexTool;
import scripting.LieDetectorScript;
import java.util.concurrent.ScheduledFuture;
public class MapleLieDetector {
public byte type;
public int attempt;
public int cid;
public String tester;
public String answer;
public boolean inProgress;
public boolean passed;
public long lasttime;
public ScheduledFuture<?> schedule;
public MapleLieDetector(final int chid) {
this.inProgress = false;
this.cid = chid;
this.reset();
}
public final boolean startLieDetector(final String tester, final boolean isItem, final boolean anotherAttempt) {
if (!anotherAttempt && ((this.isPassed() && isItem) || this.inProgress() || this.attempt == 3)) {
return false;
}
final Pair captcha = LieDetectorScript.getImageBytes();
if (captcha == null) {
return false;
}
final byte[] image = HexTool.getByteArrayFromHexString((String) captcha.getLeft());
this.answer = (String) captcha.getRight();
this.tester = tester;
this.inProgress = true;
this.type = (byte) (byte) (isItem ? 0 : 1);
++this.attempt;
final MapleCharacter chrid = MapleCharacter.getOnlineCharacterById(this.cid);
if (this.attempt < 3 && chrid != null) {
chrid.getClient().getSession().writeAndFlush(MaplePacketCreator.sendLieDetector(image, this.attempt));
}
this.schedule = EtcTimer.getInstance().schedule((Runnable) new Runnable() {
@Override
public void run() {
final MapleCharacter searchchr = MapleCharacter.getOnlineCharacterById(MapleLieDetector.this.cid);
if (!MapleLieDetector.this.isPassed() && searchchr != null) {
if (MapleLieDetector.this.attempt >= 3) {
final MapleCharacter search_chr = searchchr.getMap().getCharacterByName(tester);
if (search_chr != null && search_chr.getId() != searchchr.getId()) {
search_chr.dropMessage(5, searchchr.getName() + " 沒有通过测谎仪。");
}
MapleLieDetector.this.end();
searchchr.getClient().getSession().writeAndFlush(MaplePacketCreator.LieDetectorResponse((byte) 7, (byte) 0));
final MapleMap map = searchchr.getMap().getReturnMap();
searchchr.changeMap(map, map.getPortal(0));
Broadcast.broadcastGMMessage(MaplePacketCreator.serverNotice(6, "[GM密语] 玩家: " + searchchr.getName() + " (等级 " + (int) searchchr.getLevel() + ") 未通过测谎仪检测,疑似使用脚本外挂!"));
} else {
MapleLieDetector.this.startLieDetector(tester, isItem, true);
}
}
}
}, 60000L);
return true;
}
public final int getAttempt() {
return this.attempt;
}
public final byte getLastType() {
return this.type;
}
public final String getTester() {
return this.tester;
}
public final String getAnswer() {
return this.answer;
}
public final boolean inProgress() {
return this.inProgress;
}
public final boolean isPassed() {
return this.passed;
}
public void setPassed(final boolean passedi) {
this.passed = passedi;
}
public final boolean canDetector(final long time) {
return this.lasttime + 300000L > time;
}
public final void end() {
this.inProgress = false;
this.passed = true;
this.attempt = 0;
this.lasttime = System.currentTimeMillis();
if (this.schedule != null) {
this.schedule.cancel(false);
this.schedule = null;
}
}
public final void reset() {
this.tester = "";
this.answer = "";
this.attempt = 0;
this.inProgress = false;
this.passed = false;
}
}

View File

@ -0,0 +1,188 @@
package client;
import server.life.MapleLifeFactory;
import tools.FileoutputUtil;
import java.util.Map.Entry;
import java.util.Iterator;
import java.util.LinkedHashMap;
import constants.GameConstants;
import java.util.Map;
import server.quest.MapleQuest;
import java.io.Serializable;
public class MapleQuestStatus implements Serializable {
private static final long serialVersionUID = 91795419934134L;
private final transient MapleQuest quest;
private byte status;
private Map<Integer, Integer> killedMobs;
private int npc;
private long completionTime;
private int forfeited;
private String customData;
public MapleQuestStatus(final MapleQuest quest, final int status) {
this.killedMobs = null;
this.forfeited = 0;
this.quest = quest;
this.setStatus((byte) status);
this.completionTime = System.currentTimeMillis();
if (status == 1 && !quest.getRelevantMobs().isEmpty()) {
this.registerMobs();
}
}
public MapleQuestStatus(final MapleQuest quest, final byte status, final int npc) {
this.killedMobs = null;
this.forfeited = 0;
this.quest = quest;
this.setStatus(status);
this.setNpc(npc);
this.completionTime = System.currentTimeMillis();
if (status == 1 && !quest.getRelevantMobs().isEmpty()) {
this.registerMobs();
}
}
public final MapleQuest getQuest() {
return this.quest;
}
public final byte getStatus() {
return this.status;
}
public final void setStatus(final byte status) {
this.status = status;
}
public final int getNpc() {
return this.npc;
}
public final void setNpc(final int npc) {
this.npc = npc;
}
public boolean isCustom() {
return GameConstants.isCustomQuest(this.quest.getId());
}
private void registerMobs() {
this.killedMobs = (Map<Integer, Integer>) new LinkedHashMap();
final Iterator<Integer> iterator = this.quest.getRelevantMobs().keySet().iterator();
while (iterator.hasNext()) {
final int i = ((Integer) iterator.next()).intValue();
this.killedMobs.put(Integer.valueOf(i), Integer.valueOf(0));
}
}
private int maxMob(final int mobid) {
for (final Entry<Integer, Integer> qs : this.quest.getRelevantMobs().entrySet()) {
if (((Integer) qs.getKey()).intValue() == mobid) {
return ((Integer) qs.getValue()).intValue();
}
}
return 0;
}
public final boolean mobKilled(final int id, final int skillID) {
try {
if (this.quest != null && this.quest.getSkillID() > 0 && this.quest.getSkillID() != skillID) {
return false;
}
final Integer mob = (Integer) this.killedMobs.get(Integer.valueOf(id));
if (mob != null) {
final int mo = this.maxMob(id);
if (mob.intValue() >= mo) {
return false;
}
this.killedMobs.put(Integer.valueOf(id), Integer.valueOf(Math.min(mob.intValue() + 1, mo)));
return true;
} else {
for (final Entry<Integer, Integer> mo2 : this.killedMobs.entrySet()) {
if (this.questCount(((Integer) mo2.getKey()).intValue(), id)) {
final int mobb = this.maxMob(((Integer) mo2.getKey()).intValue());
if (((Integer) mo2.getValue()).intValue() >= mobb) {
return false;
}
this.killedMobs.put(mo2.getKey(), Integer.valueOf(Math.min(((Integer) mo2.getValue()).intValue() + 1, mobb)));
return true;
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
FileoutputUtil.outError("logs/杀死怪物计次异常.txt", (Throwable) ex);
}
return false;
}
private boolean questCount(final int mo, final int id) {
if (MapleLifeFactory.getQuestCount(mo) != null) {
final Iterator<Integer> iterator = MapleLifeFactory.getQuestCount(mo).iterator();
while (iterator.hasNext()) {
final int i = ((Integer) iterator.next()).intValue();
if (i == id) {
return true;
}
}
}
return false;
}
public final void setMobKills(final int id, final int count) {
if (this.killedMobs == null) {
this.registerMobs();
}
this.killedMobs.put(Integer.valueOf(id), Integer.valueOf(count));
}
public final boolean hasMobKills() {
return this.killedMobs != null && this.killedMobs.size() > 0;
}
public final int getMobKills(final int id) {
final Integer mob = (Integer) this.killedMobs.get(Integer.valueOf(id));
if (mob == null) {
return 0;
}
return mob.intValue();
}
public final Map<Integer, Integer> getMobKills() {
return this.killedMobs;
}
public final long getCompletionTime() {
return this.completionTime;
}
public final void setCompletionTime(final long completionTime) {
this.completionTime = completionTime;
}
public final int getForfeited() {
return this.forfeited;
}
public final void setForfeited(final int forfeited) {
if (forfeited >= this.forfeited) {
this.forfeited = forfeited;
return;
}
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 this.customData;
}
}

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

@ -0,0 +1,68 @@
package client;
public enum MapleStat {
SKIN(1),
FACE(2),
HAIR(4),
LEVEL(64),
JOB(128),
STR(256),
DEX(512),
INT(1024),
LUK(2048),
HP(4096),
MAXHP(8192),
MP(16384),
MAXMP(32768),
AVAILABLEAP(65536),
AVAILABLESP(131072),
EXP(262144),
FAME(524288),
MESO(1048576),
PET(56),
GACHAPONEXP(2097152);
private final int i;
private MapleStat(final int i) {
this.i = i;
}
public int getValue() {
return this.i;
}
public static final MapleStat getByValue(final int value) {
for (final MapleStat stat : values()) {
if (stat.i == value) {
return stat;
}
}
return null;
}
public enum Temp {
STR(1),
DEX(2),
INT(4),
LUK(8),
WATK(16),
WDEF(32),
MATK(64),
MDEF(128),
ACC(256),
AVOID(512),
SPEED(1024),
JUMP(2048);
private final int i;
private Temp(final int i) {
this.i = i;
}
public int getValue() {
return this.i;
}
}
}

4
src/client/MobVac.java Normal file
View File

@ -0,0 +1,4 @@
package client;
public class MobVac extends Thread {
}

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

@ -0,0 +1,180 @@
package client;
import tools.MaplePacketCreator;
import tools.packet.MonsterBookPacket;
import server.MapleItemInformationProvider;
import tools.data.MaplePacketLittleEndianWriter;
import java.sql.ResultSet;
import java.sql.PreparedStatement;
import java.sql.Connection;
import java.sql.SQLException;
import tools.FileoutputUtil;
import java.util.LinkedHashMap;
import database.DBConPool;
import java.util.Iterator;
import constants.GameConstants;
import java.util.Map.Entry;
import java.util.Map;
import java.io.Serializable;
public class MonsterBook implements Serializable {
private static final long serialVersionUID = 7179541993413738569L;
private boolean changed;
private int SpecialCard;
private int NormalCard;
private int BookLevel;
private final Map<Integer, Integer> cards;
public MonsterBook(final Map<Integer, Integer> cards) {
this.changed = false;
this.SpecialCard = 0;
this.NormalCard = 0;
this.BookLevel = 1;
this.cards = cards;
for (final Entry<Integer, Integer> card : cards.entrySet()) {
if (GameConstants.isSpecialCard(((Integer) card.getKey()).intValue())) {
this.SpecialCard += ((Integer) card.getValue()).intValue();
} else {
this.NormalCard += ((Integer) card.getValue()).intValue();
}
}
this.calculateLevel();
}
public Map<Integer, Integer> getCards() {
return this.cards;
}
public final int getTotalCards() {
return this.SpecialCard + this.NormalCard;
}
public final int getLevelByCard(final int cardid) {
return (this.cards.get(Integer.valueOf(cardid)) == null) ? 0 : ((Integer) this.cards.get(Integer.valueOf(cardid))).intValue();
}
public static final MonsterBook loadCards(final int charid) throws SQLException {
try (final Connection con = (Connection) DBConPool.getInstance().getDataSource().getConnection();
final PreparedStatement ps = con.prepareStatement("SELECT * FROM monsterbook WHERE charid = ? ORDER BY cardid ASC")) {
ps.setInt(1, charid);
Map<Integer, Integer> cards;
try (final ResultSet rs = ps.executeQuery()) {
cards = (Map<Integer, Integer>) new LinkedHashMap();
while (rs.next()) {
cards.put(Integer.valueOf(rs.getInt("cardid")), Integer.valueOf(rs.getInt("level")));
}
rs.close();
}
ps.close();
con.close();
return new MonsterBook(cards);
} catch (SQLException ex) {
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
return null;
}
}
public final void saveCards(final int charid, final Connection con) throws SQLException {
if (!this.changed || this.cards.isEmpty()) {
return;
}
try {
PreparedStatement ps = con.prepareStatement("DELETE FROM monsterbook WHERE charid = ?");
ps.setInt(1, charid);
ps.execute();
ps.close();
boolean first = true;
final StringBuilder query = new StringBuilder();
for (final Entry<Integer, Integer> all : this.cards.entrySet()) {
if (first) {
first = false;
query.append("INSERT INTO monsterbook VALUES (DEFAULT,");
} else {
query.append(",(DEFAULT,");
}
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 (Exception se) {
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) se);
}
}
private void calculateLevel() {
final int Size = this.NormalCard + this.SpecialCard;
this.BookLevel = 8;
for (int i = 0; i < 8; ++i) {
if (Size <= GameConstants.getBookLevel(i)) {
this.BookLevel = i + 1;
break;
}
}
}
public final void addCardPacket(final MaplePacketLittleEndianWriter mplew) {
mplew.writeShort(this.cards.size());
for (final Entry<Integer, Integer> all : this.cards.entrySet()) {
mplew.writeShort(GameConstants.getCardShortId(((Integer) all.getKey()).intValue()));
mplew.write(((Integer) all.getValue()).intValue());
}
}
public final void addCharInfoPacket(final int bookcover, final MaplePacketLittleEndianWriter mplew) {
mplew.writeInt(this.BookLevel);
mplew.writeInt(this.NormalCard);
mplew.writeInt(this.SpecialCard);
mplew.writeInt(this.NormalCard + this.SpecialCard);
mplew.writeInt(MapleItemInformationProvider.getInstance().getCardMobId(bookcover));
}
public final void updateCard(final MapleClient c, final int cardid) {
c.sendPacket(MonsterBookPacket.changeCover(cardid));
}
public final void addCard(final MapleClient c, final int cardid) {
this.changed = true;
c.getPlayer().getMap().broadcastMessage(c.getPlayer(), MonsterBookPacket.showForeginCardEffect(c.getPlayer().getId()), false);
if (this.cards.containsKey(Integer.valueOf(cardid))) {
final int levels = ((Integer) this.cards.get(Integer.valueOf(cardid))).intValue();
if (levels >= 5) {
c.sendPacket(MonsterBookPacket.addCard(true, cardid, levels));
} else {
if (GameConstants.isSpecialCard(cardid)) {
++this.SpecialCard;
} else {
++this.NormalCard;
}
c.sendPacket(MonsterBookPacket.addCard(false, cardid, levels));
c.sendPacket(MonsterBookPacket.showGainCard(cardid));
c.sendPacket(MaplePacketCreator.showSpecialEffect(15));
this.cards.put(Integer.valueOf(cardid), Integer.valueOf(levels + 1));
this.calculateLevel();
}
return;
}
if (GameConstants.isSpecialCard(cardid)) {
++this.SpecialCard;
} else {
++this.NormalCard;
}
this.cards.put(Integer.valueOf(cardid), Integer.valueOf(1));
c.sendPacket(MonsterBookPacket.addCard(false, cardid, 1));
c.sendPacket(MonsterBookPacket.showGainCard(cardid));
c.sendPacket(MaplePacketCreator.showSpecialEffect(15));
this.calculateLevel();
}
}

View File

@ -0,0 +1,102 @@
package client;
import tools.data.MaplePacketLittleEndianWriter;
import server.Randomizer;
public class PlayerRandomStream {
private transient long seed1;
private transient long seed2;
private transient long seed3;
private transient long seed1_;
private transient long seed2_;
private transient long seed3_;
private transient long seed1__;
private transient long seed2__;
private transient long seed3__;
private transient long seed1___;
private transient long seed2___;
private transient long seed3___;
public PlayerRandomStream() {
final int v4 = 5;
this.CRand32__Seed(Randomizer.nextLong(), 803157710L, 803157710L);
}
public final void CRand32__Seed(final long s1, final long s2, final long s3) {
this.seed1 = (s1 | 0x100000L);
this.seed2 = (s2 | 0x1000L);
this.seed3 = (s3 | 0x10L);
this.seed1_ = (s1 | 0x100000L);
this.seed2_ = (s2 | 0x1000L);
this.seed3_ = (s3 | 0x10L);
this.seed1__ = (s1 | 0x100000L);
this.seed2__ = (s2 | 0x1000L);
this.seed3__ = (s3 | 0x10L);
}
public final long CRand32__Random() {
final long v4 = this.seed1;
final long v5 = this.seed2;
final long v6 = this.seed3;
final long v7 = this.seed1;
final long v8 = (v4 & 0xFFFFFFFFFFFFFFFEL) << 12 ^ ((v7 & 0x7FFC0L) ^ v4 >> 13) >> 6;
final long v9 = 16L * (v5 & 0xFFFFFFFFFFFFFFF8L) ^ (v5 >> 2 ^ (v5 & 0x3F800000L)) >> 23;
final long v10 = (v6 & 0xFFFFFFFFFFFFFFF0L) << 17 ^ (v6 >> 3 ^ (v6 & 0x1FFFFF00L)) >> 8;
this.seed3_ = (v10 & 0xFFFFFFFFL);
this.seed1_ = (v8 & 0xFFFFFFFFL);
this.seed2_ = (v9 & 0xFFFFFFFFL);
return (v8 ^ v9 ^ v10) & 0xFFFFFFFFL;
}
public final long CRand32__Random_Character() {
final long v4 = this.seed1_;
final long v5 = this.seed2_;
final long v6 = this.seed3_;
final long v7 = this.seed1_;
final long v8 = (v4 & 0xFFFFFFFFFFFFFFFEL) << 12 ^ ((v7 & 0x7FFC0L) ^ v4 >> 13) >> 6;
final long v9 = 16L * (v5 & 0xFFFFFFFFFFFFFFF8L) ^ (v5 >> 2 ^ (v5 & 0x3F800000L)) >> 23;
final long v10 = (v6 & 0xFFFFFFFFFFFFFFF0L) << 17 ^ (v6 >> 3 ^ (v6 & 0x1FFFFF00L)) >> 8;
this.seed3_ = (v10 & 0xFFFFFFFFL);
this.seed1_ = (v8 & 0xFFFFFFFFL);
this.seed2_ = (v9 & 0xFFFFFFFFL);
return (v8 ^ v9 ^ v10) & 0xFFFFFFFFL;
}
public final long CRand32__Random_CheckDamageMiss() {
final long v4 = this.seed1__;
final long v5 = this.seed2__;
final long v6 = this.seed3__;
final long v7 = this.seed1__;
final long v8 = (v4 & 0xFFFFFFFFFFFFFFFEL) << 12 ^ ((v7 & 0x7FFC0L) ^ v4 >> 13) >> 6;
final long v9 = 16L * (v5 & 0xFFFFFFFFFFFFFFF8L) ^ (v5 >> 2 ^ (v5 & 0x3F800000L)) >> 23;
final long v10 = (v6 & 0xFFFFFFFFFFFFFFF0L) << 17 ^ (v6 >> 3 ^ (v6 & 0x1FFFFF00L)) >> 8;
this.seed3_ = (v10 & 0xFFFFFFFFL);
this.seed1_ = (v8 & 0xFFFFFFFFL);
this.seed2_ = (v9 & 0xFFFFFFFFL);
return (v8 ^ v9 ^ v10) & 0xFFFFFFFFL;
}
public final long CRand32__Random_ForMonster() {
final long v4 = this.seed1___;
final long v5 = this.seed2___;
final long v6 = this.seed3___;
final long v7 = this.seed1___;
final long v8 = (v4 & 0xFFFFFFFFFFFFFFFEL) << 12 ^ ((v7 & 0x7FFC0L) ^ v4 >> 13) >> 6;
final long v9 = 16L * (v5 & 0xFFFFFFFFFFFFFFF8L) ^ (v5 >> 2 ^ (v5 & 0x3F800000L)) >> 23;
final long v10 = (v6 & 0xFFFFFFFFFFFFFFF0L) << 17 ^ (v6 >> 3 ^ (v6 & 0x1FFFFF00L)) >> 8;
this.seed3_ = (v10 & 0xFFFFFFFFL);
this.seed1_ = (v8 & 0xFFFFFFFFL);
this.seed2_ = (v9 & 0xFFFFFFFFL);
return (v8 ^ v9 ^ v10) & 0xFFFFFFFFL;
}
public final void connectData(final MaplePacketLittleEndianWriter mplew) {
final long v5 = this.CRand32__Random();
final long s2 = this.CRand32__Random();
final long v6 = this.CRand32__Random();
this.CRand32__Seed(v5, s2, v6);
mplew.writeInt((int) v5);
mplew.writeInt((int) s2);
mplew.writeInt((int) v6);
}
}

1515
src/client/PlayerStats.java Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,4 @@
package client;
public class RockPaperScissors {
}

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

@ -0,0 +1,312 @@
package client;
import constants.GameConstants;
import java.util.Iterator;
import provider.MapleDataTool;
import provider.MapleData;
import java.util.ArrayList;
import server.life.Element;
import server.MapleStatEffect;
import java.util.List;
public class Skill implements ISkill {
private String name;
private final List<MapleStatEffect> effects;
private Element element;
private byte level;
private final int id;
private int animationTime;
private int requiredSkill;
private int masterLevel;
private boolean action;
private boolean invisible;
private boolean chargeskill;
private boolean timeLimited;
public Skill(final int id) {
this.name = "";
this.effects = (List<MapleStatEffect>) new ArrayList();
this.id = id;
}
public void setName(final String name) {
this.name = name;
}
@Override
public int getId() {
return this.id;
}
@Override
public String getName() {
return this.name;
}
public static final Skill loadFromData(final int id, final MapleData data) {
final Skill ret = new Skill(id);
boolean isBuff = false;
final int skillType = MapleDataTool.getInt("skillType", data, -1);
final String elem = MapleDataTool.getString("elemAttr", data, null);
if (elem != null) {
ret.element = Element.getFromChar(elem.charAt(0));
} else {
ret.element = Element.NEUTRAL;
}
ret.invisible = (MapleDataTool.getInt("invisible", data, 0) > 0);
ret.timeLimited = (MapleDataTool.getInt("timeLimited", data, 0) > 0);
ret.masterLevel = MapleDataTool.getInt("masterLevel", data, 0);
final MapleData effect = data.getChildByPath("effect");
if (skillType != -1) {
if (skillType == 2) {
isBuff = true;
}
} else {
final MapleData action_ = data.getChildByPath("action");
final MapleData hit = data.getChildByPath("hit");
final MapleData ball = data.getChildByPath("ball");
boolean action = false;
if (action_ == null) {
if (data.getChildByPath("prepare/action") != null) {
action = true;
} else {
switch (id) {
case 3101005:
case 4221001:
case 4321000:
case 4321001:
case 4331001:
case 5201001:
case 5221009: {
action = true;
break;
}
}
}
} else {
action = true;
}
ret.action = action;
isBuff = (effect != null && hit == null && ball == null);
isBuff |= (action_ != null && MapleDataTool.getString("0", action_, "").equals("alert2"));
switch (id) {
case 2111002:
case 2111003:
case 2121001:
case 2221001:
case 2301002:
case 2321001:
case 4211001:
case 12111005: {
isBuff = false;
break;
}
case 1004:
case 1026:
case 1111002:
case 1111007:
case 1211009:
case 1311007:
case 1320009:
case 4111001:
case 4211003:
case 4321000:
case 4331003:
case 4341002:
case 5001005:
case 5110001:
case 5111005:
case 5121003:
case 5121009:
case 5211001:
case 5211002:
case 5211006:
case 5220002:
case 5220011:
case 9001004:
case 9101004:
case 10001004:
case 10001026:
case 11111001:
case 12101005:
case 13111005:
case 15001003:
case 15100004:
case 15101006:
case 15111002:
case 15111005:
case 15111006:
case 20001004:
case 20001026:
case 20011004:
case 20011026:
case 21000000:
case 21101003:
case 22121001:
case 22131001:
case 22141002:
case 22151002:
case 22151003:
case 22171000:
case 22171004:
case 22181000:
case 22181003:
case 30001004:
case 30001026:
case 32001003:
case 32101002:
case 32101003:
case 32110000:
case 32120000:
case 32120001:
case 33111003:
case 35001001:
case 35001002:
case 35101002:
case 35101007:
case 35101009:
case 35111007:
case 35120000:
case 35121005:
case 35121006:
case 35121013: {
isBuff = true;
break;
}
}
}
ret.chargeskill = (data.getChildByPath("keydown") != null);
for (final MapleData level : data.getChildByPath("level")) {
ret.effects.add(MapleStatEffect.loadSkillEffectFromData(level, id, isBuff, Byte.parseByte(level.getName())));
}
final MapleData reqDataRoot = data.getChildByPath("req");
if (reqDataRoot != null) {
for (final MapleData reqData : reqDataRoot.getChildren()) {
ret.requiredSkill = Integer.parseInt(reqData.getName());
ret.level = (byte) MapleDataTool.getInt(reqData, 1);
}
}
ret.animationTime = 0;
if (effect != null) {
for (final MapleData effectEntry : effect) {
final Skill skill = ret;
skill.animationTime += MapleDataTool.getIntConvert("delay", effectEntry, 0);
}
}
return ret;
}
@Override
public MapleStatEffect getEffect(final int level) {
if (this.effects.size() < level) {
if (this.effects.size() > 0) {
return (MapleStatEffect) this.effects.get(this.effects.size() - 1);
}
return null;
} else {
if (level <= 0) {
return (MapleStatEffect) this.effects.get(0);
}
return (MapleStatEffect) this.effects.get(level - 1);
}
}
public MapleStatEffect getEffect1(final int level) {
if (this.effects.size() <= level) {
for (int a = 0; a < this.effects.size(); ++a) {
if (((MapleStatEffect) this.effects.get(a)).getLevel() == level) {
return (MapleStatEffect) this.effects.get(a);
}
}
return null;
}
if (level <= 0) {
return (MapleStatEffect) this.effects.get(0);
}
return (MapleStatEffect) this.effects.get(level - 1);
}
@Override
public boolean hasAction() {
return this.action;
}
@Override
public boolean isChargeSkill() {
return this.chargeskill;
}
@Override
public boolean isInvisible() {
return this.invisible;
}
@Override
public boolean hasRequiredSkill() {
return this.level > 0;
}
@Override
public int getRequiredSkillLevel() {
return this.level;
}
@Override
public int getRequiredSkillId() {
return this.requiredSkill;
}
@Override
public byte getMaxLevel() {
return (byte) this.effects.size();
}
@Override
public boolean canBeLearnedBy(final int job) {
final int jid = job;
final int skillForJob = this.id / 10000;
return jid / 100 == skillForJob / 100 && jid / 1000 == skillForJob / 1000 && (!GameConstants.isAdventurer(skillForJob) || GameConstants.isAdventurer(job)) && (!GameConstants.isKOC(skillForJob) || GameConstants.isKOC(job)) && (!GameConstants.isAran(skillForJob) || GameConstants.isAran(job)) && skillForJob / 10 % 10 <= jid / 10 % 10 && skillForJob % 10 <= jid % 10;
}
@Override
public boolean isTimeLimited() {
return this.timeLimited;
}
@Override
public boolean isFourthJob() {
if (this.id / 10000 >= 2212 && this.id / 10000 < 3000) {
return this.id / 10000 % 10 >= 7;
}
if (this.id / 10000 >= 430 && this.id / 10000 <= 434) {
return this.id / 10000 % 10 == 4 || this.getMasterLevel() > 0;
}
return this.id / 10000 % 10 == 2;
}
@Override
public Element getElement() {
return this.element;
}
@Override
public int getAnimationTime() {
return this.animationTime;
}
@Override
public int getMasterLevel() {
return this.masterLevel;
}
@Override
public boolean isBeginnerSkill() {
final int jobId = this.id / 10000;
return jobId == 0 || jobId == 1000 || jobId == 2000 || jobId == 2001 || jobId == 3000;
}
}

View File

@ -0,0 +1,16 @@
package client;
import java.io.Serializable;
public class SkillEntry implements Serializable {
private static final long serialVersionUID = 9179541993413738569L;
public final byte skillevel;
public final byte masterlevel;
public final long expiration;
public SkillEntry(final byte skillevel, final byte masterlevel, final long expiration) {
this.skillevel = skillevel;
this.masterlevel = masterlevel;
this.expiration = expiration;
}
}

View File

@ -0,0 +1,110 @@
package client;
import java.util.HashMap;
import java.util.Collection;
import tools.StringUtil;
import java.util.Iterator;
import provider.MapleDataDirectoryEntry;
import provider.MapleDataProvider;
import provider.MapleDataTool;
import java.util.ArrayList;
import provider.MapleDataFileEntry;
import provider.MapleDataProviderFactory;
import tools.FileoutputUtil;
import provider.MapleData;
import java.util.List;
import java.util.Map;
public class SkillFactory {
private static final Map<Integer, ISkill> skills = new HashMap();
private static final Map<Integer, List<Integer>> summonSkills = new HashMap();
private static final Map<Integer, SummonSkillEntry> summonSkillsInfo = new HashMap();
private static final MapleData stringSkills = MapleDataProviderFactory.getDataProvider("String.wz").getData("Skill.img");
public static void LoadSkillInformaion() {
System.out.println("[" + FileoutputUtil.CurrentReadable_Time() + "][信息]:初始化技能信息列表");
final MapleDataProvider skillWZ = MapleDataProviderFactory.getDataProvider("Skill.wz");
final MapleDataDirectoryEntry root = skillWZ.getRoot();
for (final MapleDataFileEntry topDir : root.getFiles()) {
if (topDir.getName().length() <= 8) {
for (final MapleData data : skillWZ.getData(topDir.getName())) {
if (data.getName().equals("skill")) {
for (final MapleData subData : data) {
if (subData != null) {
final int skillId = Integer.parseInt(subData.getName());
final Skill skil = Skill.loadFromData(skillId, subData);
List<Integer> job = SkillFactory.summonSkills.get(Integer.valueOf(skillId / 10000));
if (job == null) {
job = (List<Integer>) new ArrayList();
SkillFactory.summonSkills.put(Integer.valueOf(skillId / 10000), job);
}
job.add(Integer.valueOf(skillId));
skil.setName(getName(skillId));
SkillFactory.skills.put(Integer.valueOf(skillId), skil);
final MapleData summon_data = subData.getChildByPath("summon/attack1/info");
if (summon_data == null) {
continue;
}
final SummonSkillEntry sse = new SummonSkillEntry();
sse.attackAfter = (short) MapleDataTool.getInt("attackAfter", summon_data, 999999);
sse.type = (byte) MapleDataTool.getInt("type", summon_data, 0);
sse.mobCount = (byte) MapleDataTool.getInt("mobCount", summon_data, 1);
SkillFactory.summonSkillsInfo.put(Integer.valueOf(skillId), sse);
}
}
}
}
}
}
}
public static final ISkill getSkill(final int id) {
if (!SkillFactory.skills.isEmpty()) {
return (ISkill) SkillFactory.skills.get(Integer.valueOf(id));
}
return null;
}
public static long getDefaultSExpiry(final ISkill skill) {
if (skill == null) {
return -1L;
}
return skill.isTimeLimited() ? (System.currentTimeMillis() + 2592000000L) : -1L;
}
public static final List<Integer> getSkillsByJob(final int jobId) {
return SkillFactory.summonSkills.get(Integer.valueOf(jobId));
}
public static final String getSkillName(final int id) {
final ISkill skil = getSkill(id);
if (skil != null) {
return skil.getName();
}
return "";
}
public static final String getName(final int id) {
String strId = Integer.toString(id);
strId = StringUtil.getLeftPaddedStr(strId, '0', 7);
final MapleData skillroot = SkillFactory.stringSkills.getChildByPath(strId);
if (skillroot != null) {
return MapleDataTool.getString(skillroot.getChildByPath("name"), "");
}
return "";
}
public static final SummonSkillEntry getSummonData(final int skillid) {
return (SummonSkillEntry) SkillFactory.summonSkillsInfo.get(Integer.valueOf(skillid));
}
public static final Collection<ISkill> getAllSkills() {
return SkillFactory.skills.values();
}
}

View File

@ -0,0 +1,79 @@
package client;
import java.io.Serializable;
public class SkillMacro implements Serializable {
private static final long serialVersionUID = -63413738569L;
private int macroId;
private int skill1;
private int skill2;
private int skill3;
private String name;
private int shout;
private int position;
public SkillMacro(final int skill1, final int skill2, final int skill3, final String name, final int shout, final int position) {
this.skill1 = skill1;
this.skill2 = skill2;
this.skill3 = skill3;
this.name = name;
this.shout = shout;
this.position = position;
}
public int getMacroId() {
return this.macroId;
}
public int getSkill1() {
return this.skill1;
}
public int getSkill2() {
return this.skill2;
}
public int getSkill3() {
return this.skill3;
}
public String getName() {
return this.name;
}
public int getShout() {
return this.shout;
}
public int getPosition() {
return this.position;
}
public void setMacroId(final int macroId) {
this.macroId = macroId;
}
public void setSkill1(final int skill1) {
this.skill1 = skill1;
}
public void setSkill2(final int skill2) {
this.skill2 = skill2;
}
public void setSkill3(final int skill3) {
this.skill3 = skill3;
}
public void setName(final String name) {
this.name = name;
}
public void setShout(final int shout) {
this.shout = shout;
}
public void setPosition(final int position) {
this.position = position;
}
}

View File

@ -0,0 +1,7 @@
package client;
public class SummonSkillEntry {
public byte type;
public byte mobCount;
public short attackAfter;
}

View File

@ -0,0 +1,516 @@
package client.anticheat;
import java.util.Iterator;
import java.util.List;
import java.util.Comparator;
import java.util.ArrayList;
import java.util.Collections;
import tools.StringUtil;
import client.MapleCharacterUtil;
import constants.PiPiConfig;
import handling.world.World.Broadcast;
import tools.MaplePacketCreator;
import constants.WorldConstants;
import client.SkillFactory;
import tools.FileoutputUtil;
import gui.Start;
import client.MapleBuffStat;
import constants.GameConstants;
import server.Timer.CheatTimer;
import java.util.LinkedHashMap;
import java.util.concurrent.ScheduledFuture;
import java.awt.Point;
import client.MapleCharacter;
import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class CheatTracker {
private final ReentrantReadWriteLock lock;
private final Lock rL;
private final Lock wL;
private final Map<CheatingOffense, CheatingOffenseEntry> offenses;
private final WeakReference<MapleCharacter> chr;
private long lastAttackTime;
private int inMapIimeCount;
private int lastAttackTickCount;
private byte Attack_tickResetCount;
private long Server_ClientAtkTickDiff;
private long lastDamage;
private long takingDamageSince;
private int numSequentialDamage;
private long lastDamageTakenTime;
private byte numZeroDamageTaken;
private int numSequentialSummonAttack;
private long summonSummonTime;
private int numSameDamage;
private Point lastMonsterMove;
private int monsterMoveCount;
private int attacksWithoutHit;
private byte dropsPerSecond;
private long lastDropTime;
private byte msgsPerSecond;
private long lastMsgTime;
private ScheduledFuture<?> invalidationTask;
private int gm_message;
private int lastTickCount;
private int tickSame;
private long lastASmegaTime;
private long[] lastTime;
private long lastSaveTime;
private long lastLieDetectorTime;
private long lastLieTime;
private long TV = 0;
public CheatTracker(final MapleCharacter chr) {
this.lock = new ReentrantReadWriteLock();
this.rL = this.lock.readLock();
this.wL = this.lock.writeLock();
this.offenses = (Map<CheatingOffense, CheatingOffenseEntry>) new LinkedHashMap();
this.lastAttackTime = 0L;
this.inMapIimeCount = 0;
this.lastAttackTickCount = 0;
this.Attack_tickResetCount = 0;
this.Server_ClientAtkTickDiff = 0L;
this.lastDamage = 0L;
this.numSequentialDamage = 0;
this.lastDamageTakenTime = 0L;
this.numZeroDamageTaken = 0;
this.numSequentialSummonAttack = 0;
this.summonSummonTime = 0L;
this.numSameDamage = 0;
this.attacksWithoutHit = 0;
this.dropsPerSecond = 0;
this.lastDropTime = 0L;
this.msgsPerSecond = 0;
this.lastMsgTime = 0L;
this.gm_message = 100;
this.lastTickCount = 0;
this.tickSame = 0;
this.lastASmegaTime = 0L;
this.lastTime = new long[6];
this.lastSaveTime = 0L;
this.lastLieDetectorTime = 0L;
this.lastLieTime = 0L;
this.chr = new WeakReference(chr);
this.invalidationTask = CheatTimer.getInstance().register((Runnable) new InvalidationTask(), 60000L);
this.takingDamageSince = System.currentTimeMillis();
}
public final void checkAttack(final int skillId, final int tickcount) {
short AtkDelay = GameConstants.getAttackDelay(skillId);
if (((MapleCharacter) this.chr.get()).getBuffedValue(MapleBuffStat.BODY_PRESSURE) != null) {
AtkDelay /= 6;
}
if (((MapleCharacter) this.chr.get()).getBuffedValue(MapleBuffStat.BOOSTER) != null) {
AtkDelay = (short) (int) ((double) AtkDelay / 1.5);
}
if (((MapleCharacter) this.chr.get()).getBuffedValue(MapleBuffStat.SPEED_INFUSION) != null) {
AtkDelay = (short) (int) ((double) AtkDelay / 1.35);
}
if (GameConstants.isAran((int) ((MapleCharacter) this.chr.get()).getJob())) {
AtkDelay = (short) (int) ((double) AtkDelay / 1.4);
}
if (((MapleCharacter) this.chr.get()).getJob() >= 500 && ((MapleCharacter) this.chr.get()).getJob() <= 512) {
AtkDelay = 0;
}
if (skillId == 21101003 || skillId == 5110001) {
AtkDelay = 0;
}
if (tickcount - this.lastAttackTickCount < AtkDelay && GameConstants.getWuYanChi(skillId) && ((Integer) Start.ConfigValuesMap.get("攻速检测")).intValue() > 0) {
FileoutputUtil.logToFile("logs/Hack/攻击速度异常.txt", "\r\n " + FileoutputUtil.NowTime() + " 玩家:" + ((MapleCharacter) this.chr.get()).getName() + " 职业:" + (int) ((MapleCharacter) this.chr.get()).getJob() + "\u3000技能: " + skillId + "(" + SkillFactory.getSkillName(skillId) + ") check: " + (tickcount - this.lastAttackTickCount) + " AtkDelay: " + (int) AtkDelay);
if (WorldConstants.WUYANCHI) {
Broadcast.broadcastGMMessage(MaplePacketCreator.serverNotice(6, "[GM密语] ID " + ((MapleCharacter) this.chr.get()).getId() + " " + ((MapleCharacter) this.chr.get()).getName() + " 攻击速度异常,技能: " + skillId + "(" + SkillFactory.getSkillName(skillId) + ")"));
}
}
if (((MapleCharacter) this.chr.get()).getDebugMessage()) {
((MapleCharacter) this.chr.get()).dropMessage("Delay [" + skillId + "] = " + (tickcount - this.lastAttackTickCount) + ", " + (int) AtkDelay);
}
if (WorldConstants.LieDetector) {
this.lastAttackTime = System.currentTimeMillis();
if (this.chr.get() != null && this.lastAttackTime - ((MapleCharacter) this.chr.get()).getChangeTime() > 60000L) {
((MapleCharacter) this.chr.get()).setChangeTime(false);
if (!GameConstants.isBossMap(((MapleCharacter) this.chr.get()).getMapId()) && ((MapleCharacter) this.chr.get()).getEventInstance() == null && ((MapleCharacter) this.chr.get()).getMap().getMobsSize() >= 1) {
++this.inMapIimeCount;
if (this.inMapIimeCount >= 30) {
Broadcast.broadcastGMMessage(MaplePacketCreator.serverNotice(6, "[GM密语] ID " + ((MapleCharacter) this.chr.get()).getId() + " " + ((MapleCharacter) this.chr.get()).getName() + " 打怪时间超过 30 分钟,该玩家可能在挂机。 "));
}
if (this.inMapIimeCount >= 30) {
this.inMapIimeCount = 0;
((MapleCharacter) this.chr.get()).startLieDetector(false);
Broadcast.broadcastGMMessage(MaplePacketCreator.serverNotice(6, "[GM密语] ID " + ((MapleCharacter) this.chr.get()).getId() + " " + ((MapleCharacter) this.chr.get()).getName() + " 打怪时间超过 30 分钟,系统启动测谎仪系统。 "));
}
}
}
}
final long STime_TC = System.currentTimeMillis() - (long) tickcount;
if (this.Server_ClientAtkTickDiff - STime_TC > 1000L && GameConstants.getWuYanChi(skillId) && ((Integer) Start.ConfigValuesMap.get("攻速检测")).intValue() > 0 && WorldConstants.WUYANCHI) {
Broadcast.broadcastGMMessage(MaplePacketCreator.serverNotice(6, "[GM密语] ID " + ((MapleCharacter) this.chr.get()).getId() + " " + ((MapleCharacter) this.chr.get()).getName() + " 攻击速度异常,技能: " + skillId + "(" + SkillFactory.getSkillName(skillId) + ")"));
}
this.Server_ClientAtkTickDiff = STime_TC;
((MapleCharacter) this.chr.get()).updateTick(tickcount);
this.lastAttackTickCount = tickcount;
}
public final void checkTakeDamage(final int damage) {
++this.numSequentialDamage;
this.lastDamageTakenTime = System.currentTimeMillis();
if (this.lastDamageTakenTime - this.takingDamageSince / 500L < (long) this.numSequentialDamage) {
}
if (this.lastDamageTakenTime - this.takingDamageSince > 4500L) {
this.takingDamageSince = this.lastDamageTakenTime;
this.numSequentialDamage = 0;
}
if (damage == 0) {
++this.numZeroDamageTaken;
if (this.numZeroDamageTaken >= 35) {
this.numZeroDamageTaken = 0;
this.registerOffense(CheatingOffense.HIGH_AVOID, "回避率过高 ");
}
} else if (damage != -1) {
this.numZeroDamageTaken = 0;
}
}
public final void checkSameDamage(final int dmg, final double expected) {
if (dmg > 2000 && this.lastDamage == (long) dmg && this.chr.get() != null && (((MapleCharacter) this.chr.get()).getLevel() < 175 || (double) dmg > expected * 2.0)) {
++this.numSameDamage;
if (this.numSameDamage > 5) {
this.numSameDamage = 0;
this.registerOffense(CheatingOffense.SAME_DAMAGE, this.numSameDamage + " 次, 攻击伤害: " + dmg + ", 预计伤害: " + expected + " [等级: " + (int) ((MapleCharacter) this.chr.get()).getLevel() + ", 职业: " + (int) ((MapleCharacter) this.chr.get()).getJob() + "]");
}
} else {
this.lastDamage = (long) dmg;
this.numSameDamage = 0;
}
}
public final void checkMoveMonster(final Point pos) {
if (pos == this.lastMonsterMove) {
++this.monsterMoveCount;
if (this.monsterMoveCount > 10) {
this.monsterMoveCount = 0;
}
} else {
this.lastMonsterMove = pos;
this.monsterMoveCount = 1;
}
}
public final void resetSummonAttack() {
this.summonSummonTime = System.currentTimeMillis();
this.numSequentialSummonAttack = 0;
}
public final boolean checkSummonAttack() {
++this.numSequentialSummonAttack;
return true;
}
public final void checkDrop() {
this.checkDrop(false);
}
public final void checkDrop(final boolean dc) {
if (System.currentTimeMillis() - this.lastDropTime < 1000L) {
++this.dropsPerSecond;
if (this.dropsPerSecond >= (dc ? 32 : 16) && this.chr.get() != null && !((MapleCharacter) this.chr.get()).isGM()) {
if (dc) {
((MapleCharacter) this.chr.get()).getClient().getSession().close();
} else {
((MapleCharacter) this.chr.get()).getClient().setMonitored(true);
}
}
} else {
this.dropsPerSecond = 0;
}
this.lastDropTime = System.currentTimeMillis();
}
public boolean canAvatarSmega2() {
long time = 10000L;
if (this.chr.get() != null) {
if (((MapleCharacter) this.chr.get()).getId() == 845 || ((MapleCharacter) this.chr.get()).getId() == 5247 || ((MapleCharacter) this.chr.get()).getId() == 12048) {
time = 20000L;
}
if (this.lastASmegaTime + time > System.currentTimeMillis() && !((MapleCharacter) this.chr.get()).isGM()) {
return false;
}
}
this.lastASmegaTime = System.currentTimeMillis();
return true;
}
public synchronized boolean GMSpam(final int limit, int type) {
if (type < 0 || this.lastTime.length < type) {
type = 1;
}
if (System.currentTimeMillis() < (long) limit + this.lastTime[type]) {
return true;
}
this.lastTime[type] = System.currentTimeMillis();
return false;
}
public final void checkMsg() {
if (System.currentTimeMillis() - this.lastMsgTime < 1000L) {
++this.msgsPerSecond;
} else {
this.msgsPerSecond = 0;
}
this.lastMsgTime = System.currentTimeMillis();
}
public final int getAttacksWithoutHit() {
return this.attacksWithoutHit;
}
public final void setAttacksWithoutHit(final boolean increase) {
if (increase) {
++this.attacksWithoutHit;
} else {
this.attacksWithoutHit = 0;
}
}
public final void registerOffense(final CheatingOffense offense) {
this.registerOffense(offense, null);
}
public final void registerOffense(final CheatingOffense offense, final String param) {
final MapleCharacter chrhardref = (MapleCharacter) this.chr.get();
if (chrhardref == null || !offense.isEnabled() || chrhardref.isClone()) {
return;
}
if (((MapleCharacter) this.chr.get()).hasGmLevel(5)) {
}
CheatingOffenseEntry entry = null;
this.rL.lock();
try {
entry = (CheatingOffenseEntry) this.offenses.get(offense);
} finally {
this.rL.unlock();
}
if (entry != null && entry.isExpired()) {
this.expireEntry(entry);
entry = null;
}
if (entry == null) {
entry = new CheatingOffenseEntry(offense, chrhardref.getId());
}
if (param != null) {
entry.setParam(param);
}
entry.incrementCount();
if (offense.shouldAutoban(entry.getCount())) {
final byte type = offense.getBanType();
if (type != 1) {
if (type == 2) {
final String outputFileName = "断线";
Broadcast.broadcastGMMessage(MaplePacketCreator.serverNotice(6, "[GM密语] " + chrhardref.getName() + " 自动断线 类別: " + offense.toString() + " 原因: " + ((param == null) ? "" : (" - " + param))));
FileoutputUtil.logToFile("logs/Hack/" + outputFileName + ".txt", "\r\n " + FileoutputUtil.NowTime() + " 玩家:" + ((MapleCharacter) this.chr.get()).getName() + " 项目:" + offense.toString() + " 原因: " + ((param == null) ? "" : (" - " + param)));
chrhardref.getClient().getSession().close();
} else if (type == 3) {
boolean ban = true;
String outputFileName = "封锁";
final String show = "使用违法程式练功";
String real = "";
if (offense.toString() == "ITEMVAC_SERVER") {
outputFileName = "全图吸物";
real = "使用全图吸物";
if (!PiPiConfig.getAutoban()) {
ban = false;
}
} else if (offense.toString() == "FAST_SUMMON_ATTACK") {
outputFileName = "召唤兽无延迟";
real = "使用召唤兽无延迟攻击";
} else if (offense.toString() == "MOB_VAC") {
outputFileName = "吸怪";
real = "使用吸怪";
if (!PiPiConfig.getAutoban()) {
ban = false;
}
} else if (offense.toString() == "ATTACK_FARAWAY_MONSTER_BAN") {
outputFileName = "全图打";
real = "使用全图打";
if (!PiPiConfig.getAutoban()) {
ban = false;
}
} else {
ban = false;
Broadcast.broadcastGMMessage(MaplePacketCreator.serverNotice(6, "[GM密语] " + MapleCharacterUtil.makeMapleReadable(chrhardref.getName()) + " (编号: " + chrhardref.getId() + " )使用外挂! " + StringUtil.makeEnumHumanReadable(offense.name()) + ((param == null) ? "" : (" - " + param))));
}
if (!((MapleCharacter) this.chr.get()).hasGmLevel(1)) {
if (ban) {
if (((Integer) Start.ConfigValuesMap.get("全服通告")).intValue() > 0) {
FileoutputUtil.logToFile("logs/Hack/Ban/" + outputFileName + ".txt", "\r\n " + FileoutputUtil.NowTime() + " 玩家:" + ((MapleCharacter) this.chr.get()).getName() + " 项目:" + offense.toString() + " 原因: " + ((param == null) ? "" : (" - " + param)));
Broadcast.broadcastMessage(MaplePacketCreator.serverNotice(6, "[封锁系统] " + chrhardref.getName() + " 因为" + show + "而被管理员永久停权。"));
Broadcast.broadcastGMMessage(MaplePacketCreator.serverNotice(6, "[GM密语] " + chrhardref.getName() + " " + real + "自动封锁! "));
}
if (((Integer) Start.ConfigValuesMap.get("封停IP")).intValue() > 0) {
chrhardref.ban(chrhardref.getName() + real, true, true, false);
}
if (((Integer) Start.ConfigValuesMap.get("封停MAC")).intValue() > 0) {
chrhardref.getClient().banMacs();
}
if (((Integer) Start.ConfigValuesMap.get("封停账号")).intValue() > 0) {
chrhardref.getClient().getSession().close();
}
}
}
}
}
this.gm_message = 100;
return;
}
this.wL.lock();
try {
this.offenses.put(offense, entry);
} finally {
this.wL.unlock();
}
CheatingOffensePersister.getInstance().persistEntry(entry);
}
public void updateTick(final int newTick) {
if (newTick == this.lastTickCount) {
++this.tickSame;
} else {
this.tickSame = 0;
}
this.lastTickCount = newTick;
}
public final void expireEntry(final CheatingOffenseEntry coe) {
this.wL.lock();
try {
this.offenses.remove(coe.getOffense());
} finally {
this.wL.unlock();
}
}
public final int getPoints() {
int ret = 0;
this.rL.lock();
CheatingOffenseEntry[] offenses_copy;
try {
offenses_copy = (CheatingOffenseEntry[]) this.offenses.values().toArray(new CheatingOffenseEntry[this.offenses.size()]);
} finally {
this.rL.unlock();
}
for (final CheatingOffenseEntry entry : offenses_copy) {
if (entry.isExpired()) {
this.expireEntry(entry);
} else {
ret += entry.getPoints();
}
}
return ret;
}
public final Map<CheatingOffense, CheatingOffenseEntry> getOffenses() {
return Collections.unmodifiableMap(this.offenses);
}
public final String getSummary() {
final StringBuilder ret = new StringBuilder();
final List<CheatingOffenseEntry> offenseList = (List<CheatingOffenseEntry>) new ArrayList();
this.rL.lock();
try {
for (final CheatingOffenseEntry entry : this.offenses.values()) {
if (!entry.isExpired()) {
offenseList.add(entry);
}
}
} finally {
this.rL.unlock();
}
Collections.sort(offenseList, new Comparator<CheatingOffenseEntry>() {
@Override
public final int compare(final CheatingOffenseEntry o1, final CheatingOffenseEntry o2) {
final int thisVal = o1.getPoints();
final int anotherVal = o2.getPoints();
return (thisVal < anotherVal) ? 1 : ((thisVal == anotherVal) ? 0 : -1);
}
});
for (int to = Math.min(offenseList.size(), 4), x = 0; x < to; ++x) {
ret.append(StringUtil.makeEnumHumanReadable(((CheatingOffenseEntry) offenseList.get(x)).getOffense().name()));
ret.append(": ");
ret.append(((CheatingOffenseEntry) offenseList.get(x)).getCount());
if (x != to - 1) {
ret.append(" ");
}
}
return ret.toString();
}
public final void dispose() {
if (this.invalidationTask != null) {
this.invalidationTask.cancel(false);
}
this.invalidationTask = null;
}
public boolean canSaveDB() {
if (System.currentTimeMillis() - this.lastSaveTime < 300000L) {
return false;
}
this.lastSaveTime = System.currentTimeMillis();
return true;
}
public int getlastSaveTime() {
return (int) ((System.currentTimeMillis() - this.lastSaveTime) / 1000L);
}
public int getlastLieTime() {
return (int) ((System.currentTimeMillis() - this.lastLieTime) / 1000L);
}
public boolean canLieDetector() {
if (this.lastLieDetectorTime + 300000L > System.currentTimeMillis() && this.chr.get() != null) {
return false;
}
this.lastLieDetectorTime = System.currentTimeMillis();
return true;
}
public void resetInMapIimeCount() {
this.inMapIimeCount = 0;
}
public boolean canTV() {
if (TV + 60000 > System.currentTimeMillis()) {
return false;
}
TV = System.currentTimeMillis();
return true;
}
private final class InvalidationTask implements Runnable {
@Override
public final void run() {
CheatTracker.this.rL.lock();
CheatingOffenseEntry[] offenses_copy;
try {
offenses_copy = (CheatingOffenseEntry[]) CheatTracker.this.offenses.values().toArray((Object[]) new CheatingOffenseEntry[CheatTracker.this.offenses.size()]);
} finally {
CheatTracker.this.rL.unlock();
}
for (final CheatingOffenseEntry offense : offenses_copy) {
if (offense.isExpired()) {
CheatTracker.this.expireEntry(offense);
}
}
if (CheatTracker.this.chr.get() == null) {
CheatTracker.this.dispose();
}
}
}
}

View File

@ -0,0 +1,84 @@
package client.anticheat;
public enum CheatingOffense {
FAST_SUMMON_ATTACK((byte) 5, 6000L, 50, (byte) 3),
FASTATTACK((byte) 5, 6000L, 50, (byte) 2),
FASTATTACK2((byte) 5, 10000L, 20, (byte) 1),
MOVE_MONSTERS((byte) 1, 30000L),
FAST_HP_MP_REGEN((byte) 5, 20000L, 10, (byte) 2),
SAME_DAMAGE((byte) 2, 30000L, 150),
ATTACK_WITHOUT_GETTING_HIT((byte) 1, 30000L, 1200, (byte) 0),
HIGH_DAMAGE_MAGIC((byte) 5, 30000L, -1, (byte) 0),
HIGH_DAMAGE_MAGIC_2((byte) 10, 30000L, -1, (byte) 0),
HIGH_DAMAGE((byte) 5, 30000L, -1, (byte) 0),
HIGH_DAMAGE_2((byte) 10, 30000L, -1, (byte) 0),
EXCEED_DAMAGE_CAP((byte) 5, 60000L, 800, (byte) 0),
ATTACK_FARAWAY_MONSTER((byte) 5, 60000L, 5000),
ATTACK_FARAWAY_MONSTER_BAN((byte) 3, 60000L, 5, (byte) 3),
ATTACK_FARAWAY_MONSTER_SUMMON((byte) 5, 60000L, 200),
REGEN_HIGH_HP((byte) 1, 30000L, 1000, (byte) 2),
REGEN_HIGH_MP((byte) 1, 30000L, 1000, (byte) 2),
MOB_VAC((byte) 3, 7000L, 5, (byte) 3),
ITEMVAC_CLIENT((byte) 5, 5000L, 10),
ITEMVAC_SERVER((byte) 1, 10000L, 10, (byte) 2),
PET_ITEMVAC_CLIENT((byte) 5, 20000L, 20, (byte) 2),
PET_ITEMVAC_SERVER((byte) 3, 30000L, 20, (byte) 2),
USING_FARAWAY_PORTAL((byte) 1, 60000L, 100, (byte) 0),
AST_TAKE_DAMAG((byte) 1, 60000L, 100),
HIGH_AVOID((byte) 20, 180000L, 100),
HIGH_JUMP((byte) 1, 60000L),
MISMATCHING_BULLETCOUNT((byte) 1, 300000L),
ETC_EXPLOSION((byte) 1, 300000L),
ATTACKING_WHILE_DEAD((byte) 1, 300000L, -1, (byte) 0),
USING_UNAVAILABLE_ITEM((byte) 1, 300000L),
EXPLODING_NONEXISTANT((byte) 1, 300000L),
SUMMON_HACK((byte) 1, 300000L),
SUMMON_HACK_MOBS((byte) 1, 300000L),
ARAN_COMBO_HACK((byte) 1, 600000L, 50),
HEAL_ATTACKING_UNDEAD((byte) 20, 30000L, 2);
private final byte points;
private final long validityDuration;
private final int autobancount;
private byte bantype;
public final byte getPoints() {
return this.points;
}
public final long getValidityDuration() {
return this.validityDuration;
}
public final boolean shouldAutoban(final int count) {
return this.autobancount != -1 && count >= this.autobancount;
}
public final byte getBanType() {
return this.bantype;
}
public final void setEnabled(final boolean enabled) {
this.bantype = (byte) (byte) (enabled ? 1 : 0);
}
public final boolean isEnabled() {
return this.bantype >= 1;
}
private CheatingOffense(final byte points, final long validityDuration) {
this(points, validityDuration, -1, (byte) 1);
}
private CheatingOffense(final byte points, final long validityDuration, final int autobancount) {
this(points, validityDuration, autobancount, (byte) 1);
}
private CheatingOffense(final byte points, final long validityDuration, final int autobancount, final byte bantype) {
this.bantype = 0;
this.points = points;
this.validityDuration = validityDuration;
this.autobancount = autobancount;
this.bantype = bantype;
}
}

View File

@ -0,0 +1,64 @@
package client.anticheat;
public class CheatingOffenseEntry {
private CheatingOffense offense;
private int count;
private int characterid;
private long lastOffense;
private long firstOffense;
private String param;
private int dbid;
public CheatingOffenseEntry(final CheatingOffense offense, final int characterid) {
this.count = 0;
this.dbid = -1;
this.offense = offense;
this.characterid = characterid;
this.firstOffense = System.currentTimeMillis();
}
public CheatingOffense getOffense() {
return this.offense;
}
public int getCount() {
return this.count;
}
public int getChrfor() {
return this.characterid;
}
public void incrementCount() {
++this.count;
this.lastOffense = System.currentTimeMillis();
}
public boolean isExpired() {
return this.lastOffense < System.currentTimeMillis() - this.offense.getValidityDuration();
}
public int getPoints() {
return this.count * this.offense.getPoints();
}
public String getParam() {
return this.param;
}
public void setParam(final String param) {
this.param = param;
}
public long getLastOffenseTime() {
return this.lastOffense;
}
public int getDbId() {
return this.dbid;
}
public void setDbId(final int dbid) {
this.dbid = dbid;
}
}

View File

@ -0,0 +1,46 @@
package client.anticheat;
import server.Timer.CheatTimer;
import java.util.concurrent.locks.ReentrantLock;
import java.util.LinkedHashSet;
import java.util.concurrent.locks.Lock;
import java.util.Set;
public class CheatingOffensePersister {
private static final CheatingOffensePersister instance = new CheatingOffensePersister();
private final Set<CheatingOffenseEntry> toPersist;
private final Lock mutex;
private CheatingOffensePersister() {
this.toPersist = (Set<CheatingOffenseEntry>) new LinkedHashSet();
this.mutex = new ReentrantLock();
CheatTimer.getInstance().register((Runnable) new PersistingTask(), 61000L);
}
public static CheatingOffensePersister getInstance() {
return CheatingOffensePersister.instance;
}
public void persistEntry(final CheatingOffenseEntry coe) {
this.mutex.lock();
try {
this.toPersist.remove(coe);
this.toPersist.add(coe);
} finally {
this.mutex.unlock();
}
}
public class PersistingTask implements Runnable {
@Override
public void run() {
CheatingOffensePersister.this.mutex.lock();
try {
CheatingOffensePersister.this.toPersist.clear();
} finally {
CheatingOffensePersister.this.mutex.unlock();
}
}
}
}

View File

@ -0,0 +1,648 @@
package client.inventory;
import server.Randomizer;
import constants.GameConstants;
import java.io.Serializable;
public class Equip extends Item implements IEquip, Serializable {
private byte upgradeSlots;
private byte level;
private byte vicioushammer;
private byte enhance;
private short str;
private short dex;
private short _int;
private short luk;
private short hp;
private short mp;
private short watk;
private short matk;
private short wdef;
private short mdef;
private short acc;
private short avoid;
private short hands;
private short speed;
private short jump;
private short potential1;
private short potential2;
private short potential3;
private short hpR;
private short mpR;
private short charmExp;
private short pvpDamage;
private long itemEXP;
private int durability;
private int incSkill;
private int dd;
private int db;
private int qg;
public Equip(final int id, final short position, final byte flag) {
super(id, position, (short) 1, flag);
this.upgradeSlots = 0;
this.level = 0;
this.vicioushammer = 0;
this.enhance = 0;
this.str = 0;
this.dex = 0;
this._int = 0;
this.luk = 0;
this.hp = 0;
this.mp = 0;
this.watk = 0;
this.matk = 0;
this.wdef = 0;
this.mdef = 0;
this.acc = 0;
this.avoid = 0;
this.hands = 0;
this.speed = 0;
this.jump = 0;
this.potential1 = 0;
this.potential2 = 0;
this.potential3 = 0;
this.hpR = 0;
this.mpR = 0;
this.charmExp = 0;
this.pvpDamage = 0;
this.itemEXP = 0;
this.durability = -1;
this.incSkill = -1;
this.dd = 0;
this.db = 0;
this.qg = 0;
}
public Equip(final int id, final short position) {
super(id, position, (short) 1, (byte) 0);
this.upgradeSlots = 0;
this.level = 0;
this.vicioushammer = 0;
this.enhance = 0;
this.str = 0;
this.dex = 0;
this._int = 0;
this.luk = 0;
this.hp = 0;
this.mp = 0;
this.watk = 0;
this.matk = 0;
this.wdef = 0;
this.mdef = 0;
this.acc = 0;
this.avoid = 0;
this.hands = 0;
this.speed = 0;
this.jump = 0;
this.potential1 = 0;
this.potential2 = 0;
this.potential3 = 0;
this.hpR = 0;
this.mpR = 0;
this.charmExp = 0;
this.pvpDamage = 0;
this.itemEXP = 0;
this.durability = -1;
this.incSkill = -1;
this.dd = 0;
this.db = 0;
this.qg = 0;
}
public Equip(final int id, final short position, final int uniqueid, final byte flag) {
super(id, position, (short) 1, flag, uniqueid);
this.upgradeSlots = 0;
this.level = 0;
this.vicioushammer = 0;
this.enhance = 0;
this.str = 0;
this.dex = 0;
this._int = 0;
this.luk = 0;
this.hp = 0;
this.mp = 0;
this.watk = 0;
this.matk = 0;
this.wdef = 0;
this.mdef = 0;
this.acc = 0;
this.avoid = 0;
this.hands = 0;
this.speed = 0;
this.jump = 0;
this.potential1 = 0;
this.potential2 = 0;
this.potential3 = 0;
this.hpR = 0;
this.mpR = 0;
this.charmExp = 0;
this.pvpDamage = 0;
this.itemEXP = 0;
this.durability = -1;
this.incSkill = -1;
this.dd = 0;
this.db = 0;
this.qg = 0;
}
@Override
public IItem copy() {
final Equip ret = new Equip(this.getItemId(), this.getPosition(), this.getUniqueId(), this.getFlag());
ret.str = this.str;
ret.dex = this.dex;
ret._int = this._int;
ret.luk = this.luk;
ret.hp = this.hp;
ret.mp = this.mp;
ret.matk = this.matk;
ret.mdef = this.mdef;
ret.watk = this.watk;
ret.wdef = this.wdef;
ret.acc = this.acc;
ret.avoid = this.avoid;
ret.hands = this.hands;
ret.speed = this.speed;
ret.jump = this.jump;
ret.enhance = this.enhance;
ret.upgradeSlots = this.upgradeSlots;
ret.level = this.level;
ret.itemEXP = this.itemEXP;
ret.durability = this.durability;
ret.vicioushammer = this.vicioushammer;
ret.potential1 = this.potential1;
ret.potential2 = this.potential2;
ret.potential3 = this.potential3;
ret.charmExp = this.charmExp;
ret.pvpDamage = this.pvpDamage;
ret.hpR = this.hpR;
ret.mpR = this.mpR;
ret.incSkill = this.incSkill;
ret.dd = this.dd;
ret.db = this.db;
ret.qg = this.qg;
ret.setGiftFrom(this.getGiftFrom());
ret.setOwner(this.getOwner());
ret.setQuantity(this.getQuantity());
ret.setExpiration(this.getExpiration());
ret.setInventoryId(this.getInventoryId());
ret.setEquipOnlyId(this.getEquipOnlyId());
return ret;
}
@Override
public byte getType() {
return 1;
}
@Override
public byte getUpgradeSlots() {
return this.upgradeSlots;
}
@Override
public short getStr() {
return this.str;
}
@Override
public short getDex() {
return this.dex;
}
@Override
public short getInt() {
return this._int;
}
@Override
public short getLuk() {
return this.luk;
}
@Override
public short getHp() {
return this.hp;
}
@Override
public short getMp() {
return this.mp;
}
@Override
public short getWatk() {
return this.watk;
}
@Override
public short getMatk() {
return this.matk;
}
@Override
public short getWdef() {
return this.wdef;
}
@Override
public short getMdef() {
return this.mdef;
}
@Override
public short getAcc() {
return this.acc;
}
@Override
public short getAvoid() {
return this.avoid;
}
@Override
public short getHands() {
return this.hands;
}
@Override
public short getSpeed() {
return this.speed;
}
@Override
public short getJump() {
return this.jump;
}
public void setStr(short str) {
if (str < 0) {
str = 0;
}
this.str = str;
}
public void setDex(short dex) {
if (dex < 0) {
dex = 0;
}
this.dex = dex;
}
public void setInt(short _int) {
if (_int < 0) {
_int = 0;
}
this._int = _int;
}
public void setLuk(short luk) {
if (luk < 0) {
luk = 0;
}
this.luk = luk;
}
public void setHp(short hp) {
if (hp < 0) {
hp = 0;
}
this.hp = hp;
}
public void setMp(short mp) {
if (mp < 0) {
mp = 0;
}
this.mp = mp;
}
public void setWatk(short watk) {
if (watk < 0) {
watk = 0;
}
this.watk = watk;
}
public void setMatk(short matk) {
if (matk < 0) {
matk = 0;
}
this.matk = matk;
}
public void setWdef(short wdef) {
if (wdef < 0) {
wdef = 0;
}
this.wdef = wdef;
}
public void setMdef(short mdef) {
if (mdef < 0) {
mdef = 0;
}
this.mdef = mdef;
}
public void setAcc(short acc) {
if (acc < 0) {
acc = 0;
}
this.acc = acc;
}
public void setAvoid(short avoid) {
if (avoid < 0) {
avoid = 0;
}
this.avoid = avoid;
}
public void setHands(short hands) {
if (hands < 0) {
hands = 0;
}
this.hands = hands;
}
public void setSpeed(short speed) {
if (speed < 0) {
speed = 0;
}
this.speed = speed;
}
public void setJump(short jump) {
if (jump < 0) {
jump = 0;
}
this.jump = jump;
}
public void setdd(int dd) {
if (dd < 0) {
dd = 0;
}
this.dd = dd;
}
public void setdb(int db) {
if (db < 0) {
db = 0;
}
this.db = db;
}
public void setqg(int qg) {
if (qg < 0) {
qg = 0;
}
this.qg = qg;
}
public void setUpgradeSlots(final byte upgradeSlots) {
this.upgradeSlots = upgradeSlots;
}
@Override
public byte getLevel() {
return this.level;
}
public void setLevel(final byte level) {
this.level = level;
}
@Override
public byte getViciousHammer() {
return this.vicioushammer;
}
public void setViciousHammer(final byte ham) {
this.vicioushammer = ham;
}
@Override
public long getItemEXP() {
return this.itemEXP;
}
public void setItemEXP(long itemEXP) {
if (itemEXP < 0) {
itemEXP = 0;
}
this.itemEXP = itemEXP;
}
@Override
public long getEquipExp() {
if (this.itemEXP <= 0) {
return 0;
}
if (GameConstants.isWeapon(this.getItemId())) {
return this.itemEXP / 700000;
}
return this.itemEXP / 350000;
}
@Override
public long getEquipExpForLevel() {
if (this.getEquipExp() <= 0) {
return 0;
}
long expz = this.getEquipExp();
for (int i = this.getBaseLevel(); i <= GameConstants.getMaxLevel(this.getItemId()) && expz >= GameConstants.getExpForLevel(i, this.getItemId()); expz -= GameConstants.getExpForLevel(i, this.getItemId()), ++i) {
}
return expz;
}
@Override
public long getExpPercentage() {
if (this.getEquipLevel() < this.getBaseLevel() || this.getEquipLevel() > GameConstants.getMaxLevel(this.getItemId()) || GameConstants.getExpForLevel(this.getEquipLevel(), this.getItemId()) <= 0) {
return 0;
}
return this.getEquipExpForLevel() * 100 / GameConstants.getExpForLevel(this.getEquipLevel(), this.getItemId());
}
@Override
public int getEquipLevel() {
if (GameConstants.getMaxLevel(this.getItemId()) <= 0) {
return 0;
}
if (this.getEquipExp() <= 0) {
return this.getBaseLevel();
}
int levelz = this.getBaseLevel();
long expz = this.getEquipExp();
int i = levelz;
while (true) {
if (GameConstants.getStatFromWeapon(this.getItemId()) == null) {
if (i > GameConstants.getMaxLevel(this.getItemId())) {
break;
}
} else if (i >= GameConstants.getMaxLevel(this.getItemId())) {
break;
}
if (expz < GameConstants.getExpForLevel(i, this.getItemId())) {
break;
}
++levelz;
expz -= GameConstants.getExpForLevel(i, this.getItemId());
++i;
}
return levelz;
}
@Override
public int getBaseLevel() {
return (GameConstants.getStatFromWeapon(this.getItemId()) == null) ? 1 : 0;
}
@Override
public void setQuantity(final short quantity) {
if (quantity < 0 || quantity > 1) {
throw new RuntimeException("Setting the quantity to " + (int) quantity + " on an equip (itemid: " + this.getItemId() + ")");
}
super.setQuantity(quantity);
}
@Override
public int getDurability() {
return this.durability;
}
public void setDurability(final int dur) {
this.durability = dur;
}
@Override
public byte getEnhance() {
return this.enhance;
}
public void setEnhance(final byte en) {
this.enhance = en;
}
@Override
public short getPotential1() {
return this.potential1;
}
public void setPotential1(final short en) {
this.potential1 = en;
}
@Override
public short getPotential2() {
return this.potential2;
}
public void setPotential2(final short en) {
this.potential2 = en;
}
@Override
public short getPotential3() {
return this.potential3;
}
public void setPotential3(final short en) {
this.potential3 = en;
}
@Override
public byte getState() {
final int pots = this.potential1 + this.potential2 + this.potential3;
if (this.potential1 >= 30000 || this.potential2 >= 30000 || this.potential3 >= 30000) {
return 7;
}
if (this.potential1 >= 20000 || this.potential2 >= 20000 || this.potential3 >= 20000) {
return 6;
}
if (pots >= 1) {
return 5;
}
if (pots < 0) {
return 1;
}
return 0;
}
public void resetPotential() {
final int rank = (Randomizer.nextInt(100) < 4) ? ((Randomizer.nextInt(100) < 4) ? -7 : -6) : -5;
this.setPotential1((short) rank);
this.setPotential2((short) ((Randomizer.nextInt(10) == 1) ? rank : 0));
this.setPotential3((short) 0);
}
public void renewPotential() {
final int rank = (Randomizer.nextInt(100) < 4 && this.getState() != 7) ? (-(this.getState() + 1)) : (-this.getState());
this.setPotential1((short) rank);
this.setPotential2((short) ((this.getPotential3() > 0) ? rank : 0));
this.setPotential3((short) 0);
}
@Override
public short getHpR() {
return this.hpR;
}
public void setHpR(final short hp) {
this.hpR = hp;
}
@Override
public short getMpR() {
return this.mpR;
}
@Override
public int getdd() {
return this.dd;
}
@Override
public int getdb() {
return this.db;
}
@Override
public int getqg() {
return this.qg;
}
public void setMpR(final short mp) {
this.mpR = mp;
}
public int getIncSkill() {
return this.incSkill;
}
public void setIncSkill(final int inc) {
this.incSkill = inc;
}
public short getCharmEXP() {
return this.charmExp;
}
public void setCharmEXP(final short s) {
this.charmExp = s;
}
public short getPVPDamage() {
return this.pvpDamage;
}
public void setPVPDamage(final short p) {
this.pvpDamage = p;
}
}

View File

@ -0,0 +1,103 @@
package client.inventory;
import java.util.Arrays;
import java.util.List;
public enum EquipAdditions {
elemboost("elemVol", "elemVol", true),
mobcategory("category", "damage"),
critical("prob", "damage"),
boss("prob", "damage"),
mobdie("hpIncOnMobDie", "mpIncOnMobDie"),
hpmpchange("hpChangerPerTime", "mpChangerPerTime"),
skill("id", "level"),
statinc("incDEX", "incINT", "incLUK", "incPAD", "incSpeed", "incSTR");
private final String i1;
private final String i2;
private final String i3;
private final String i4;
private final String i5;
private final String i6;
private final boolean element;
private EquipAdditions(final String i1, final String i2) {
this.i1 = i1;
this.i2 = i2;
this.i3 = "";
this.i4 = "";
this.i5 = "";
this.i6 = "";
this.element = false;
}
private EquipAdditions(final String i1, final String i2, final boolean element) {
this.i1 = i1;
this.i2 = i2;
this.i3 = "";
this.i4 = "";
this.i5 = "";
this.i6 = "";
this.element = element;
}
private EquipAdditions(final String i1, final String i2, final String i3, final String i4, final String i5, final String i6) {
this.i1 = i1;
this.i2 = i2;
this.i3 = i3;
this.i4 = i4;
this.i5 = i5;
this.i6 = i6;
this.element = false;
}
public final String getValue1() {
return this.i1;
}
public final String getValue2() {
return this.i2;
}
public final String getValue3() {
return this.i3;
}
public final String getValue4() {
return this.i4;
}
public final String getValue5() {
return this.i5;
}
public final String getValue6() {
return this.i6;
}
public final boolean isElement() {
return this.element;
}
public static final EquipAdditions fromString(final String str) {
for (final EquipAdditions s : values()) {
if (s.name().equalsIgnoreCase(str)) {
return s;
}
}
return null;
}
public enum RingSet {
天使的祝福戒指(new Integer[]{Integer.valueOf(1112585), Integer.valueOf(1112586), Integer.valueOf(1112594)}),
职业戒指(new Integer[]{Integer.valueOf(1112427), Integer.valueOf(1112428), Integer.valueOf(1112429), Integer.valueOf(1112405), Integer.valueOf(1112445), Integer.valueOf(1112591), Integer.valueOf(1112592)}),
Evolving_Ring(new Integer[]{Integer.valueOf(1112499), Integer.valueOf(1112500), Integer.valueOf(1112501), Integer.valueOf(1112502), Integer.valueOf(1112503), Integer.valueOf(1112504), Integer.valueOf(1112505), Integer.valueOf(1112506), Integer.valueOf(1112507), Integer.valueOf(1112508), Integer.valueOf(1112509), Integer.valueOf(1112510), Integer.valueOf(1112511), Integer.valueOf(1112512), Integer.valueOf(1112513), Integer.valueOf(1112514), Integer.valueOf(1112515), Integer.valueOf(1112516), Integer.valueOf(1112517), Integer.valueOf(1112518), Integer.valueOf(1112519), Integer.valueOf(1112520), Integer.valueOf(1112521), Integer.valueOf(1112522), Integer.valueOf(1112523), Integer.valueOf(1112524), Integer.valueOf(1112525), Integer.valueOf(1112526), Integer.valueOf(1112527), Integer.valueOf(1112528), Integer.valueOf(1112529), Integer.valueOf(1112530), Integer.valueOf(1112531), Integer.valueOf(1112532), Integer.valueOf(1112533)}),
Evolving_Ring_II(new Integer[]{Integer.valueOf(1112614), Integer.valueOf(1112615), Integer.valueOf(1112616), Integer.valueOf(1112617), Integer.valueOf(1112618), Integer.valueOf(1112619), Integer.valueOf(1112620), Integer.valueOf(1112621), Integer.valueOf(1112622), Integer.valueOf(1112623), Integer.valueOf(1112624), Integer.valueOf(1112625), Integer.valueOf(1112626), Integer.valueOf(1112627), Integer.valueOf(1112628), Integer.valueOf(1112629), Integer.valueOf(1112630), Integer.valueOf(1112631), Integer.valueOf(1112632), Integer.valueOf(1112633), Integer.valueOf(1112634), Integer.valueOf(1112635), Integer.valueOf(1112636), Integer.valueOf(1112637), Integer.valueOf(1112638), Integer.valueOf(1112639), Integer.valueOf(1112640), Integer.valueOf(1112641), Integer.valueOf(1112642), Integer.valueOf(1112643), Integer.valueOf(1112644), Integer.valueOf(1112645), Integer.valueOf(1112646), Integer.valueOf(1112647), Integer.valueOf(1112648)});
public List<Integer> id;
private RingSet(final Integer[] ids) {
this.id = Arrays.asList(ids);
}
}
}

View File

@ -0,0 +1,82 @@
package client.inventory;
public interface IEquip extends IItem {
public static final int ARMOR_RATIO = 350000;
public static final int WEAPON_RATIO = 700000;
byte getUpgradeSlots();
byte getLevel();
byte getViciousHammer();
long getItemEXP();
long getExpPercentage();
int getEquipLevel();
long getEquipExp();
long getEquipExpForLevel();
int getBaseLevel();
short getStr();
short getDex();
short getInt();
short getLuk();
short getHp();
short getMp();
short getWatk();
short getMatk();
short getWdef();
short getMdef();
short getAcc();
short getAvoid();
short getHands();
short getSpeed();
short getJump();
int getDurability();
byte getEnhance();
byte getState();
short getPotential1();
short getPotential2();
short getPotential3();
short getHpR();
short getMpR();
int getdd();
int getdb();
int getqg();
public enum ScrollResult {
SUCCESS,
FAIL,
CURSE;
}
}

View File

@ -0,0 +1,59 @@
package client.inventory;
public interface IItem extends Comparable<IItem> {
byte getType();
short getPosition();
byte getFlag();
short getQuantity();
String getOwner();
String getGMLog();
int getItemId();
void setItemId(final int p0);
MaplePet getPet();
int getUniqueId();
boolean hasSetOnlyId();
long getEquipOnlyId();
long getInventoryId();
IItem copy();
IItem copyWithQuantity(final short p0);
long getExpiration();
void setFlag(final byte p0);
void setUniqueId(final int p0);
void setEquipOnlyId(final long p0);
void setInventoryId(final long p0);
void setPosition(final short p0);
void setExpiration(final long p0);
void setOwner(final String p0);
void setGMLog(final String p0);
void setQuantity(final short p0);
void setGiftFrom(final String p0);
String getGiftFrom();
MapleRing getRing();
}

View File

@ -0,0 +1,12 @@
package client.inventory;
public class InventoryException extends RuntimeException {
private static final long serialVersionUID = 1L;
public InventoryException() {
}
public InventoryException(final String msg) {
super(msg);
}
}

View File

@ -0,0 +1,301 @@
package client.inventory;
import constants.GameConstants;
import server.MapleItemInformationProvider;
import java.io.Serializable;
public class Item implements IItem, Serializable {
private int id;
private short position;
private short quantity;
private byte flag;
private long expiration;
private long inventoryitemid;
private MaplePet pet;
private int uniqueid;
private long equipOnlyId;
private String owner;
private String GameMaster_log;
private String giftFrom;
protected MapleRing ring;
public Item(final int id, final short position, final short quantity, final byte flag, final int uniqueid) {
this.expiration = -1L;
this.inventoryitemid = 0L;
this.pet = null;
this.uniqueid = -1;
this.equipOnlyId = -1L;
this.owner = "";
this.GameMaster_log = null;
this.giftFrom = "";
this.ring = null;
this.id = id;
this.position = position;
this.quantity = quantity;
this.flag = flag;
this.uniqueid = uniqueid;
this.equipOnlyId = -1L;
}
public Item(final int id, final short position, final short quantity, final byte flag) {
this.expiration = -1L;
this.inventoryitemid = 0L;
this.pet = null;
this.uniqueid = -1;
this.equipOnlyId = -1L;
this.owner = "";
this.GameMaster_log = null;
this.giftFrom = "";
this.ring = null;
this.id = id;
this.position = position;
this.quantity = quantity;
this.flag = flag;
this.equipOnlyId = -1L;
}
@Override
public Item copyWithQuantity(final short qq) {
final Item ret = new Item(this.id, this.position, qq, this.flag, this.uniqueid);
ret.pet = this.pet;
ret.owner = this.owner;
ret.GameMaster_log = this.GameMaster_log;
ret.expiration = this.expiration;
ret.giftFrom = this.giftFrom;
ret.equipOnlyId = this.equipOnlyId;
return ret;
}
public Item(final int id, final byte position, final short quantity) {
this.expiration = -1L;
this.inventoryitemid = 0L;
this.pet = null;
this.uniqueid = -1;
this.equipOnlyId = -1L;
this.owner = "";
this.GameMaster_log = null;
this.giftFrom = "";
this.ring = null;
this.id = id;
this.position = (short) position;
this.quantity = quantity;
this.equipOnlyId = -1L;
}
@Override
public IItem copy() {
final Item ret = new Item(this.id, this.position, this.quantity, this.flag, this.uniqueid);
ret.pet = this.pet;
ret.owner = this.owner;
ret.GameMaster_log = this.GameMaster_log;
ret.expiration = this.expiration;
ret.giftFrom = this.giftFrom;
ret.quantity = this.quantity;
ret.equipOnlyId = this.equipOnlyId;
return ret;
}
@Override
public final void setPosition(final short position) {
this.position = position;
if (this.pet != null) {
this.pet.setInventoryPosition(position);
}
}
@Override
public void setQuantity(final short quantity) {
this.quantity = quantity;
}
@Override
public final int getItemId() {
return this.id;
}
@Override
public void setItemId(final int ui) {
this.id = ui;
}
@Override
public final short getPosition() {
return this.position;
}
@Override
public final byte getFlag() {
return this.flag;
}
@Override
public final short getQuantity() {
return this.quantity;
}
@Override
public byte getType() {
return 2;
}
@Override
public final String getOwner() {
return this.owner;
}
@Override
public final void setOwner(final String owner) {
this.owner = owner;
}
@Override
public final void setFlag(final byte flag) {
this.flag = flag;
}
public final void setLocked(final byte flag) {
if (flag == 1) {
this.setFlag((byte) ItemFlag.LOCK.getValue());
} else if (flag == 0) {
this.setFlag((byte) (this.getFlag() - ItemFlag.LOCK.getValue()));
}
}
public final boolean getLocked() {
return this.flag == ItemFlag.LOCK.getValue();
}
@Override
public final long getExpiration() {
return this.expiration;
}
@Override
public final void setExpiration(final long expire) {
this.expiration = expire;
}
@Override
public final String getGMLog() {
return this.GameMaster_log;
}
@Override
public void setGMLog(final String GameMaster_log) {
this.GameMaster_log = GameMaster_log;
}
@Override
public final int getUniqueId() {
return this.uniqueid;
}
@Override
public final void setUniqueId(final int id) {
this.uniqueid = id;
}
@Override
public boolean hasSetOnlyId() {
final MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
return this.uniqueid <= 0 && !ii.isCash(this.id) && this.id / 1000000 == 1 && this.equipOnlyId <= 0L;
}
@Override
public long getEquipOnlyId() {
return this.equipOnlyId;
}
@Override
public void setEquipOnlyId(final long OnlyId) {
this.equipOnlyId = OnlyId;
}
@Override
public final long getInventoryId() {
return this.inventoryitemid;
}
@Override
public void setInventoryId(final long ui) {
this.inventoryitemid = ui;
}
@Override
public final MaplePet getPet() {
return this.pet;
}
public final void setPet(final MaplePet pet) {
this.pet = pet;
}
@Override
public void setGiftFrom(final String gf) {
this.giftFrom = gf;
}
@Override
public String getGiftFrom() {
return this.giftFrom;
}
@Override
public int compareTo(final IItem other) {
if (Math.abs((int) this.position) < Math.abs((int) other.getPosition())) {
return -1;
}
if (Math.abs((int) this.position) == Math.abs((int) other.getPosition())) {
return 0;
}
return 1;
}
@Override
public boolean equals(final Object obj) {
if (!(obj instanceof IItem)) {
return false;
}
final IItem ite = (IItem) obj;
return this.uniqueid == ite.getUniqueId() && this.id == ite.getItemId() && this.quantity == ite.getQuantity() && Math.abs((int) this.position) == Math.abs((int) ite.getPosition());
}
@Override
public int hashCode() {
int hash = 3;
hash = 97 * hash + this.id;
hash = 97 * hash + this.position;
hash = 97 * hash + this.quantity;
hash = 97 * hash + this.uniqueid;
return hash;
}
@Override
public String toString() {
return "物品: " + this.id + " 数量: " + (int) this.quantity;
}
@Override
public MapleRing getRing() {
if (!GameConstants.isEffectRing(this.id) || this.getUniqueId() <= 0) {
return null;
}
if (this.ring == null) {
this.ring = MapleRing.loadFromDb(this.getUniqueId(), this.position < 0);
}
return this.ring;
}
public void setRing(final MapleRing ring) {
this.ring = ring;
}
public final void setLoEQed(final byte flag) {
if (flag == 1) {
this.setFlag((byte) ItemFlag.KARMA_EQ.getValue());
} else if (flag == 0) {
this.setFlag((byte) (this.getFlag() - ItemFlag.KARMA_EQ.getValue()));
}
}
}

View File

@ -0,0 +1,24 @@
package client.inventory;
public enum ItemFlag {
LOCK(1),
SPIKES(2),
COLD(4),
UNTRADEABLE(8),
KARMA_EQ(16),
KARMA_USE(2);
private final int i;
private ItemFlag(final int i) {
this.i = i;
}
public final int getValue() {
return this.i;
}
public final boolean check(final int flag) {
return (flag & this.i) == this.i;
}
}

View File

@ -0,0 +1,23 @@
package client.inventory;
public enum ItemFlag2 {
notSale(16),
pickUpBlock(64),
only(128),
accountSharable(256),
tradeBlock(1024);
private final int i;
private ItemFlag2(final int i) {
this.i = i;
}
public final int getValue() {
return this.i;
}
public final boolean check(final int flag) {
return (flag & this.i) == this.i;
}
}

View File

@ -0,0 +1,308 @@
package client.inventory;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.sql.ResultSet;
import java.sql.PreparedStatement;
import java.sql.Connection;
import java.util.Iterator;
import java.sql.SQLException;
import tools.FileoutputUtil;
import constants.GameConstants;
import database.DBConPool;
import java.util.LinkedHashMap;
import tools.Pair;
import java.util.Map;
import java.util.Arrays;
import java.util.List;
public enum ItemLoader {
INVENTORY("inventoryitems", "inventoryequipment", 0, new String[]{"characterid"}),
STORAGE("inventoryitems", "inventoryequipment", 1, new String[]{"accountid"}),
CASHSHOP_EXPLORER("csitems", "csequipment", 2, new String[]{"accountid"}),
CASHSHOP_CYGNUS("csitems", "csequipment", 3, new String[]{"accountid"}),
CASHSHOP_ARAN("csitems", "csequipment", 4, new String[]{"accountid"}),
HIRED_MERCHANT("hiredmerchitems", "hiredmerchequipment", 5, new String[]{"packageid", "accountid"}),
DUEY("dueyitems", "dueyequipment", 6, new String[]{"packageid"}),
CASHSHOP_EVAN("csitems", "csequipment", 7, new String[]{"accountid"}),
MTS("mtsitems", "mtsequipment", 8, new String[]{"packageid"}),
MTS_TRANSFER("mtstransfer", "mtstransferequipment", 9, new String[]{"characterid"}),
CASHSHOP_DB("csitems", "csequipment", 10, new String[]{"accountid"}),
CASHSHOP_RESIST("csitems", "csequipment", 11, new String[]{"accountid"});
private final int value;
private final String table;
private final String table_equip;
private List<String> arg;
private ItemLoader(final String table, final String table_equip, final int value, final String[] arg) {
this.table = table;
this.table_equip = table_equip;
this.value = value;
this.arg = Arrays.asList(arg);
}
public int getValue() {
return this.value;
}
public Map<Long, Pair<IItem, MapleInventoryType>> loadItems(final boolean login, final Integer... id) throws SQLException {
final List<Integer> lulz = Arrays.asList(id);
final Map<Long, Pair<IItem, MapleInventoryType>> items = (Map<Long, Pair<IItem, MapleInventoryType>>) new LinkedHashMap();
if (lulz.size() != this.arg.size()) {
return items;
}
final StringBuilder query = new StringBuilder();
query.append("SELECT * FROM `");
query.append(this.table);
query.append("` LEFT JOIN `");
query.append(this.table_equip);
query.append("` USING(`inventoryitemid`) WHERE `type` = ?");
for (final String g : this.arg) {
query.append(" AND `");
query.append(g);
query.append("` = ?");
}
if (login) {
query.append(" AND `inventorytype` = ");
query.append((int) MapleInventoryType.EQUIPPED.getType());
}
try (final Connection con = (Connection) DBConPool.getInstance().getDataSource().getConnection()) {
final PreparedStatement ps = con.prepareStatement(query.toString());
ps.setInt(1, this.value);
for (int i = 0; i < lulz.size(); ++i) {
ps.setInt(i + 2, ((Integer) lulz.get(i)).intValue());
}
final ResultSet rs = ps.executeQuery();
while (rs.next()) {
final MapleInventoryType mit = MapleInventoryType.getByType(rs.getByte("inventorytype"));
if (mit.equals(MapleInventoryType.EQUIP) || mit.equals(MapleInventoryType.EQUIPPED)) {
final Equip equip = new Equip(rs.getInt("itemid"), rs.getShort("position"), rs.getInt("uniqueid"), rs.getByte("flag"));
if (!login) {
equip.setQuantity((short) 1);
equip.setInventoryId(rs.getLong("inventoryitemid"));
equip.setOwner(rs.getString("owner"));
equip.setExpiration(rs.getLong("expiredate"));
equip.setUpgradeSlots(rs.getByte("upgradeslots"));
equip.setLevel(rs.getByte("level"));
equip.setStr(rs.getShort("str"));
equip.setDex(rs.getShort("dex"));
equip.setInt(rs.getShort("int"));
equip.setLuk(rs.getShort("luk"));
equip.setHp(rs.getShort("hp"));
equip.setMp(rs.getShort("mp"));
equip.setWatk(rs.getShort("watk"));
equip.setMatk(rs.getShort("matk"));
equip.setWdef(rs.getShort("wdef"));
equip.setMdef(rs.getShort("mdef"));
equip.setAcc(rs.getShort("acc"));
equip.setAvoid(rs.getShort("avoid"));
equip.setHands(rs.getShort("hands"));
equip.setSpeed(rs.getShort("speed"));
equip.setJump(rs.getShort("jump"));
equip.setViciousHammer(rs.getByte("ViciousHammer"));
equip.setItemEXP(rs.getInt("itemEXP"));
equip.setGMLog(rs.getString("GM_Log"));
equip.setDurability(rs.getInt("durability"));
equip.setEnhance(rs.getByte("enhance"));
equip.setPotential1(rs.getShort("potential1"));
equip.setPotential2(rs.getShort("potential2"));
equip.setPotential3(rs.getShort("potential3"));
equip.setHpR(rs.getShort("hpR"));
equip.setMpR(rs.getShort("mpR"));
equip.setdd(rs.getInt("dd"));
equip.setdb(rs.getInt("db"));
equip.setqg(rs.getInt("qg"));
equip.setGiftFrom(rs.getString("sender"));
if (equip.getUniqueId() > -1 && GameConstants.isEffectRing(rs.getInt("itemid"))) {
final MapleRing ring = MapleRing.loadFromDb(equip.getUniqueId(), mit.equals(MapleInventoryType.EQUIPPED));
if (ring != null) {
equip.setRing(ring);
}
}
}
items.put(Long.valueOf(rs.getLong("inventoryitemid")), new Pair(equip.copy(), mit));
} else {
final Item item = new Item(rs.getInt("itemid"), rs.getShort("position"), rs.getShort("quantity"), rs.getByte("flag"));
item.setUniqueId(rs.getInt("uniqueid"));
item.setOwner(rs.getString("owner"));
item.setInventoryId(rs.getLong("inventoryitemid"));
item.setExpiration(rs.getLong("expiredate"));
item.setGMLog(rs.getString("GM_Log"));
item.setGiftFrom(rs.getString("sender"));
if (GameConstants.isPet(item.getItemId())) {
if (item.getUniqueId() > -1) {
final MaplePet pet = MaplePet.loadFromDb(item.getItemId(), item.getUniqueId(), item.getPosition());
if (pet != null) {
item.setPet(pet);
}
} else {
final int new_unique = MapleInventoryIdentifier.getInstance();
item.setUniqueId(new_unique);
item.setPet(MaplePet.createPet(item.getItemId(), new_unique));
}
}
items.put(Long.valueOf(rs.getLong("inventoryitemid")), new Pair(item.copy(), mit));
}
}
rs.close();
ps.close();
con.close();
} catch (SQLException ex) {
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
}
return items;
}
public void saveItems(final List<Pair<IItem, MapleInventoryType>> items, final Integer... id) throws SQLException {
try (final Connection con = (Connection) DBConPool.getInstance().getDataSource().getConnection()) {
this.saveItems(items, con, id);
con.close();
} catch (SQLException ex) {
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
}
}
public void saveItems(final List<Pair<IItem, MapleInventoryType>> items, final Connection con, final Integer... id) throws SQLException {
try {
final List<Integer> lulz = Arrays.asList(id);
if (lulz.size() != this.arg.size()) {
return;
}
final StringBuilder query = new StringBuilder();
query.append("DELETE FROM `");
query.append(this.table);
query.append("` WHERE `type` = ? AND (`");
query.append((String) this.arg.get(0));
query.append("` = ?");
if (this.arg.size() > 1) {
for (int i = 1; i < this.arg.size(); ++i) {
query.append(" OR `");
query.append((String) this.arg.get(i));
query.append("` = ?");
}
}
query.append(")");
PreparedStatement ps = con.prepareStatement(query.toString());
ps.setInt(1, this.value);
for (int j = 0; j < lulz.size(); ++j) {
ps.setInt(j + 2, ((Integer) lulz.get(j)).intValue());
}
ps.executeUpdate();
ps.close();
if (items == null) {
return;
}
final StringBuilder query_2 = new StringBuilder("INSERT INTO `");
query_2.append(this.table);
query_2.append("` (");
for (final String g : this.arg) {
query_2.append(g);
query_2.append(", ");
}
query_2.append("itemid, inventorytype, position, quantity, owner, GM_Log, uniqueid, expiredate, flag, `type`, sender, equipOnlyId) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?");
for (final String g : this.arg) {
query_2.append(", ?");
}
query_2.append(")");
ps = con.prepareStatement(query_2.toString(), 1);
final PreparedStatement pse = con.prepareStatement("INSERT INTO " + this.table_equip + " VALUES (DEFAULT, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?,?,?)", 1);
for (final Pair<IItem, MapleInventoryType> pair : items) {
final IItem item = (IItem) pair.getLeft();
final MapleInventoryType mit = (MapleInventoryType) pair.getRight();
int k = 1;
for (int x = 0; x < lulz.size(); ++x) {
ps.setInt(k, ((Integer) lulz.get(x)).intValue());
++k;
}
ps.setInt(k, item.getItemId());
ps.setInt(k + 1, (int) mit.getType());
ps.setInt(k + 2, (int) item.getPosition());
ps.setInt(k + 3, (int) item.getQuantity());
ps.setString(k + 4, item.getOwner());
ps.setString(k + 5, item.getGMLog());
ps.setInt(k + 6, item.getUniqueId());
ps.setLong(k + 7, item.getExpiration());
ps.setByte(k + 8, item.getFlag());
ps.setByte(k + 9, (byte) this.value);
ps.setString(k + 10, item.getGiftFrom());
ps.setLong(k + 11, item.getEquipOnlyId());
ps.executeUpdate();
if (mit.equals(MapleInventoryType.EQUIP) || mit.equals(MapleInventoryType.EQUIPPED)) {
try (final ResultSet rs = ps.getGeneratedKeys()) {
if (!rs.next()) {
throw new RuntimeException("Inserting item failed.");
}
pse.setLong(1, rs.getLong(1));
}
final IEquip equip = (IEquip) item;
pse.setInt(2, (int) equip.getUpgradeSlots());
pse.setInt(3, (int) equip.getLevel());
pse.setInt(4, (int) equip.getStr());
pse.setInt(5, (int) equip.getDex());
pse.setInt(6, (int) equip.getInt());
pse.setInt(7, (int) equip.getLuk());
pse.setInt(8, (int) equip.getHp());
pse.setInt(9, (int) equip.getMp());
pse.setInt(10, (int) equip.getWatk());
pse.setInt(11, (int) equip.getMatk());
pse.setInt(12, (int) equip.getWdef());
pse.setInt(13, (int) equip.getMdef());
pse.setInt(14, (int) equip.getAcc());
pse.setInt(15, (int) equip.getAvoid());
pse.setInt(16, (int) equip.getHands());
pse.setInt(17, (int) equip.getSpeed());
pse.setInt(18, (int) equip.getJump());
pse.setInt(19, (int) equip.getViciousHammer());
pse.setLong(20, equip.getItemEXP());
pse.setInt(21, equip.getDurability());
pse.setByte(22, equip.getEnhance());
pse.setInt(23, (int) equip.getPotential1());
pse.setInt(24, (int) equip.getPotential2());
pse.setInt(25, (int) equip.getPotential3());
pse.setInt(26, (int) equip.getHpR());
pse.setInt(27, (int) equip.getMpR());
pse.setInt(28, (int) equip.getdd());
pse.setInt(29, (int) equip.getdb());
pse.setInt(30, (int) equip.getqg());
pse.executeUpdate();
}
}
pse.close();
ps.close();
} catch (SQLException ex) {
System.out.println(ex);
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
}
}
public static boolean isExistsByUniqueid(final int uniqueid) {
for (final ItemLoader il : values()) {
final StringBuilder query = new StringBuilder();
query.append("SELECT * FROM `inventoryitems` WHERE `type` = ? AND uniqueid = ?");
try (final Connection con = (Connection) DBConPool.getInstance().getDataSource().getConnection()) {
final PreparedStatement ps = con.prepareStatement(query.toString());
ps.setInt(1, il.value);
ps.setInt(2, uniqueid);
final ResultSet rs = ps.executeQuery();
if (rs.first()) {
rs.close();
ps.close();
con.close();
return true;
}
rs.close();
ps.close();
con.close();
} catch (SQLException ex) {
Logger.getLogger(ItemLoader.class.getName()).log(Level.SEVERE, null, (Throwable) ex);
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
}
}
return false;
}
}

View File

@ -0,0 +1,294 @@
package client.inventory;
import java.util.LinkedList;
import server.MapleItemInformationProvider;
import tools.MaplePacketCreator;
import client.MapleCharacter;
import constants.GameConstants;
import java.util.Collection;
import java.util.Collections;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.io.Serializable;
public class MapleInventory implements Iterable<IItem>, Serializable {
private Map<Short, IItem> inventory;
private byte slotLimit;
private MapleInventoryType type;
public MapleInventory(final MapleInventoryType type) {
this.slotLimit = 0;
this.inventory = (Map<Short, IItem>) new LinkedHashMap();
this.type = type;
}
public void addSlot(final byte slot) {
this.slotLimit += slot;
if (this.slotLimit > 96) {
this.slotLimit = 96;
}
}
public byte getSlotLimit() {
return this.slotLimit;
}
public void setSlotLimit(byte slot) {
if (slot > 96) {
slot = 96;
}
this.slotLimit = slot;
}
public IItem findById(final int itemId) {
for (final IItem item : this.inventory.values()) {
if (item.getItemId() == itemId) {
return item;
}
}
return null;
}
public IItem findByUniqueId(final int itemId) {
for (final IItem item : this.inventory.values()) {
if (item.getUniqueId() == itemId) {
return item;
}
}
return null;
}
public int countById(final int itemId) {
int possesed = 0;
for (final IItem item : this.inventory.values()) {
if (item.getItemId() == itemId) {
possesed += item.getQuantity();
}
}
return possesed;
}
public List<IItem> listById(final int itemId) {
final List<IItem> ret = (List<IItem>) new ArrayList();
for (final IItem item : this.inventory.values()) {
if (item.getItemId() == itemId) {
ret.add(item);
}
}
if (ret.size() > 1) {
Collections.sort(ret);
}
return ret;
}
public Collection<IItem> list() {
return this.inventory.values();
}
public ArrayList<Equip> equlist() {
Collection<IItem> values = this.inventory.values();
final ArrayList<Equip> ret = new ArrayList<>();
for (final IItem item : values) {
if (item instanceof Equip) {
ret.add((Equip) item);
}
}
return ret;
}
public short addItem(final IItem item) {
final short slotId = this.getNextFreeSlot();
if (slotId < 0) {
return -1;
}
this.inventory.put(Short.valueOf(slotId), item);
item.setPosition(slotId);
return slotId;
}
public short addItem(final Item item, final int slotId) {
this.inventory.put(Short.valueOf((short) slotId), item);
item.setPosition((short) slotId);
return (short) slotId;
}
public short addItem(final IItem item, final int slotId) {
this.inventory.put(Short.valueOf((short) slotId), item);
item.setPosition((short) slotId);
return (short) slotId;
}
public void addFromDB(final IItem item) {
if (item.getPosition() < 0 && !this.type.equals(MapleInventoryType.EQUIPPED)) {
return;
}
this.inventory.put(Short.valueOf(item.getPosition()), item);
}
public void move(final short sSlot, final short dSlot, final short slotMax) {
if (dSlot > this.slotLimit) {
return;
}
final Item source = (Item) this.inventory.get(Short.valueOf(sSlot));
final Item target = (Item) this.inventory.get(Short.valueOf(dSlot));
if (source == null) {
throw new InventoryException("Trying to move empty slot");
}
if (target == null) {
source.setPosition(dSlot);
this.inventory.put(Short.valueOf(dSlot), source);
this.inventory.remove(Short.valueOf(sSlot));
} else if (target.getItemId() == source.getItemId() && !GameConstants.isThrowingStar(source.getItemId()) && !GameConstants.isBullet(source.getItemId()) && target.getOwner().equals(source.getOwner()) && target.getExpiration() == source.getExpiration()) {
if (this.type.getType() == MapleInventoryType.EQUIP.getType() || this.type.getType() == MapleInventoryType.CASH.getType()) {
this.swap((IItem) target, (IItem) source);
} else if (source.getQuantity() + target.getQuantity() > slotMax) {
source.setQuantity((short) (source.getQuantity() + target.getQuantity() - slotMax));
target.setQuantity(slotMax);
} else {
target.setQuantity((short) (source.getQuantity() + target.getQuantity()));
this.inventory.remove(Short.valueOf(sSlot));
}
} else {
this.swap((IItem) target, (IItem) source);
}
}
private void swap(final IItem source, final IItem target) {
this.inventory.remove(Short.valueOf(source.getPosition()));
this.inventory.remove(Short.valueOf(target.getPosition()));
final short swapPos = source.getPosition();
source.setPosition(target.getPosition());
target.setPosition(swapPos);
this.inventory.put(Short.valueOf(source.getPosition()), source);
this.inventory.put(Short.valueOf(target.getPosition()), target);
}
public IItem getItem(final short slot) {
return (IItem) this.inventory.get(Short.valueOf(slot));
}
public void removeItem(final short slot) {
this.removeItem(slot, (short) 1, false);
}
public void removeItem(final short slot, final short quantity, final boolean allowZero) {
this.removeItem(slot, quantity, allowZero, null);
}
public void removeItem(final short slot, final short quantity, final boolean allowZero, final MapleCharacter chr) {
final IItem item = (IItem) this.inventory.get(Short.valueOf(slot));
if (item == null) {
return;
}
item.setQuantity((short) (item.getQuantity() - quantity));
if (item.getQuantity() < 0) {
item.setQuantity((short) 0);
}
if (item.getQuantity() == 0 && !allowZero) {
this.removeSlot(slot);
}
if (chr != null) {
chr.getClient().sendPacket(MaplePacketCreator.modifyInventory(false, new ModifyInventory(3, item)));
chr.dropMessage(5, "加载道具[" + MapleItemInformationProvider.getInstance().getName(item.getItemId()) + "]因到期而消失了。");
}
}
public void removeSlot(final short slot) {
this.inventory.remove(Short.valueOf(slot));
}
public boolean isFull() {
return this.inventory.size() >= this.slotLimit;
}
public boolean isFull(final int margin) {
return this.inventory.size() + margin >= this.slotLimit;
}
public short getNextFreeSlot() {
if (this.isFull()) {
return -1;
}
for (short i = 1; i <= this.slotLimit; ++i) {
if (!this.inventory.keySet().contains(Short.valueOf(i))) {
return i;
}
}
return -1;
}
public int getNumSlotLimit() {
return this.inventory.size();
}
public short getNumFreeSlot() {
if (this.isFull()) {
return 0;
}
byte free = 0;
for (short i = 1; i <= this.slotLimit; ++i) {
if (!this.inventory.keySet().contains(Short.valueOf(i))) {
++free;
}
}
return (short) free;
}
public MapleInventoryType getType() {
return this.type;
}
@Override
public Iterator<IItem> iterator() {
return Collections.unmodifiableCollection(this.inventory.values()).iterator();
}
public IItem getItemByInventoryItemId(final Long inventoryitemid) {
for (final IItem item : this.inventory.values()) {
if (item.getInventoryId() == inventoryitemid.longValue()) {
return item;
}
}
return null;
}
public List<Item> listByEquipOnlyId(final long equipOnlyId) {
final List ret = new ArrayList();
for (final IItem item : this.inventory.values()) {
if (item.getEquipOnlyId() > 0L && item.getEquipOnlyId() == equipOnlyId) {
ret.add(item);
}
}
if (ret.size() > 1) {
Collections.sort(ret);
}
return (List<Item>) ret;
}
public List<Item> newList() {
if (this.inventory.size() <= 0) {
return Collections.emptyList();
}
return new LinkedList(this.inventory.values());
}
public List<Integer> listIds() {
final List ret = new ArrayList();
for (final IItem item : this.inventory.values()) {
if (!ret.contains(Integer.valueOf(item.getItemId()))) {
ret.add(Integer.valueOf(item.getItemId()));
}
}
if (ret.size() > 1) {
Collections.sort(ret);
}
return (List<Integer>) ret;
}
}

View File

@ -0,0 +1,116 @@
package client.inventory;
import java.sql.ResultSet;
import java.sql.PreparedStatement;
import java.sql.Connection;
import tools.FileoutputUtil;
import database.DBConPool;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.atomic.AtomicInteger;
import java.io.Serializable;
public class MapleInventoryIdentifier implements Serializable {
private static final long serialVersionUID = 21830921831301L;
private AtomicInteger runningUID;
private ReentrantReadWriteLock rwl;
private Lock readLock;
private Lock writeLock;
private static MapleInventoryIdentifier instance = new MapleInventoryIdentifier();
public MapleInventoryIdentifier() {
this.rwl = new ReentrantReadWriteLock();
this.readLock = this.rwl.readLock();
this.writeLock = this.rwl.writeLock();
this.runningUID = new AtomicInteger(0);
this.getNextUniqueId();
}
public static int getInstance() {
return MapleInventoryIdentifier.instance.getNextUniqueId();
}
public int getNextUniqueId() {
if (this.grabRunningUID() <= 0) {
this.setRunningUID(this.initUID());
}
this.incrementRunningUID();
return this.grabRunningUID();
}
public int grabRunningUID() {
this.readLock.lock();
try {
return this.runningUID.get();
} finally {
this.readLock.unlock();
}
}
public void incrementRunningUID() {
this.setRunningUID(this.grabRunningUID() + 1);
}
public void setRunningUID(final int rUID) {
if (rUID < this.grabRunningUID()) {
return;
}
this.writeLock.lock();
try {
this.runningUID.set(rUID);
} finally {
this.writeLock.unlock();
}
}
public int initUID() {
int ret = 0;
if (this.grabRunningUID() > 0) {
return this.grabRunningUID();
}
try (final Connection con = (Connection) DBConPool.getInstance().getDataSource().getConnection()) {
final int[] ids = new int[4];
PreparedStatement ps = con.prepareStatement("SELECT MAX(uniqueid) FROM inventoryitems");
ResultSet rs = ps.executeQuery();
if (rs.next()) {
ids[0] = rs.getInt(1) + 1;
}
rs.close();
ps.close();
ps = con.prepareStatement("SELECT MAX(petid) FROM pets");
rs = ps.executeQuery();
if (rs.next()) {
ids[1] = rs.getInt(1) + 1;
}
rs.close();
ps.close();
ps = con.prepareStatement("SELECT MAX(ringid) FROM rings");
rs = ps.executeQuery();
if (rs.next()) {
ids[2] = rs.getInt(1) + 1;
}
rs.close();
ps.close();
ps = con.prepareStatement("SELECT MAX(partnerringid) FROM rings");
rs = ps.executeQuery();
if (rs.next()) {
ids[3] = rs.getInt(1) + 1;
}
rs.close();
ps.close();
for (int i = 0; i < 4; ++i) {
if (ids[i] > ret) {
ret = ids[i];
}
}
con.close();
} catch (Exception e) {
e.printStackTrace();
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) e);
}
return ret;
}
}

View File

@ -0,0 +1,55 @@
package client.inventory;
public enum MapleInventoryType {
UNDEFINED(0),
FACE(0),
HAIR(0),
EQUIP(1),
USE(2),
SETUP(3),
ETC(4),
CASH(5),
EQUIPPED(-1);
final byte type;
private MapleInventoryType(final int type) {
this.type = (byte) type;
}
public byte getType() {
return this.type;
}
public short getBitfieldEncoding() {
return (short) (2 << this.type);
}
public static MapleInventoryType getByType(final byte type) {
for (final MapleInventoryType l : values()) {
if (l.getType() == type) {
return l;
}
}
return null;
}
public static MapleInventoryType getByWZName(final String name) {
if (name.equals("Install")) {
return MapleInventoryType.SETUP;
}
if (name.equals("Consume")) {
return MapleInventoryType.USE;
}
if (name.equals("Etc")) {
return MapleInventoryType.ETC;
}
if (name.equals("Cash")) {
return MapleInventoryType.CASH;
}
if (name.equals("Pet")) {
return MapleInventoryType.CASH;
}
return MapleInventoryType.UNDEFINED;
}
}

View File

@ -0,0 +1,199 @@
package client.inventory;
import server.Randomizer;
import server.Timer.MapTimer;
import client.MapleBuffStat;
import server.MapleInventoryManipulator;
import tools.MaplePacketCreator;
import constants.GameConstants;
import gui.Start;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import tools.FileoutputUtil;
import tools.FilePrinter;
import java.sql.Connection;
import java.util.concurrent.ScheduledFuture;
import client.MapleCharacter;
import java.lang.ref.WeakReference;
import java.io.Serializable;
public class MapleMount implements Serializable {
public byte fatigue;
public byte level;
private static final long serialVersionUID = 9179541993413738569L;
private final int skillid;
private int itemid;
private int exp;
private transient boolean changed;
private long lastFatigue;
private final transient WeakReference<MapleCharacter> owner;
private ScheduledFuture<?> tirednessSchedule;
private boolean Riding;
public MapleMount(final MapleCharacter owner, final int id, final int skillid, final byte fatigue, final byte level, final int exp) {
this.changed = false;
this.lastFatigue = 0L;
this.Riding = false;
this.itemid = id;
this.skillid = skillid;
this.fatigue = fatigue;
this.level = level;
this.exp = exp;
this.owner = new WeakReference(owner);
}
public void saveMount(final int charid, final Connection con) {
if (!this.changed) {
return;
}
try (final PreparedStatement ps = con.prepareStatement("UPDATE mountdata set `Level` = ?, `Exp` = ?, `Fatigue` = ? WHERE characterid = ?")) {
ps.setByte(1, this.level);
ps.setInt(2, this.exp);
ps.setByte(3, this.fatigue);
ps.setInt(4, charid);
ps.executeUpdate();
} catch (SQLException ex) {
FilePrinter.printError("MapleMount.txt", (Throwable) ex, "saveMount");
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
}
}
public int getItemId() {
return this.itemid;
}
public int getSkillId() {
return this.skillid;
}
public byte getFatigue() {
return this.fatigue;
}
public int getExp() {
return this.exp;
}
public byte getLevel() {
return this.level;
}
public void setItemId(final int c) {
this.changed = true;
this.itemid = c;
}
public void setFatigue(final byte amount) {
this.changed = true;
this.fatigue += amount;
if (this.fatigue < 0) {
this.fatigue = 0;
}
}
public void setExp(final int c) {
this.changed = true;
this.exp = c;
}
public void setLevel(final byte c) {
this.changed = true;
this.level = c;
}
public void increaseFatigue() {
final MapleCharacter chr = (MapleCharacter) this.owner.get();
this.changed = true;
++this.fatigue;
if (chr != null && ((Integer) Start.ConfigValuesMap.get("坐骑恢复开关")).intValue() > 0) {
final int itemid = 2260000;
final int toUse = chr.getItemQuantity(2260000, false);
final MapleMount mount = chr.getMount();
boolean pd = false;
if (chr.getItemQuantity(((Integer) Start.ConfigValuesMap.get("坐骑恢复道具")).intValue(), false) > 0) {
pd = true;
}
if (pd && this.fatigue >= ((Integer) Start.ConfigValuesMap.get("坐骑恢复频率")).intValue() && toUse > 0) {
final int fatigue = mount.getFatigue();
boolean levelup = false;
mount.setFatigue((byte) (-30));
if (fatigue > 0) {
mount.increaseExp();
final int level = mount.getLevel();
if (level < 30 && mount.getExp() >= GameConstants.getMountExpNeededForLevel(level + 1)) {
mount.setLevel((byte) (level + 1));
levelup = true;
}
}
chr.getMap().broadcastMessage(MaplePacketCreator.updateMount(chr, levelup));
if (chr != null) {
MapleInventoryManipulator.removeById(chr.getClient(), MapleInventoryType.USE, 2260000, 1, false, false);
chr.getClient().getSession().write(MaplePacketCreator.getShowItemGain(2260000, (short) (-1), true));
chr.dropMessage(5, "VIP自动使用骑宠疲劳药水,目前骑宠疲劳:" + fatigue);
}
}
}
if (chr != null && chr.getMap() != null) {
chr.getMap().broadcastMessage(MaplePacketCreator.updateMount(chr, false));
}
if (((Integer) Start.ConfigValuesMap.get("坐骑不饥饿开关")).intValue() > 0) {
this.fatigue = 100;
}
if (this.fatigue > 99) {
this.fatigue = 95;
if (chr != null) {
chr.cancelEffectFromBuffStat(MapleBuffStat.MONSTER_RIDING);
}
}
}
public final boolean canTire(final long now) {
return this.lastFatigue > 0L && this.lastFatigue + 30000L < now;
}
public long getTiredness() {
return this.lastFatigue;
}
public void startSchedule() {
this.changed = true;
this.tirednessSchedule = MapTimer.getInstance().register((Runnable) new Runnable() {
@Override
public void run() {
if (MapleMount.this.Riding) {
MapleMount.this.increaseFatigue();
if (MapleMount.this.owner.get() != null) {
}
} else {
MapleMount.this.Riding = true;
}
}
}, 60000L);
}
public void cancelSchedule() {
if (this.tirednessSchedule != null) {
this.Riding = false;
this.tirednessSchedule.cancel(false);
}
}
public void increaseExp() {
int e;
if (this.level >= 1 && this.level <= 7) {
e = Randomizer.nextInt(10) + 15;
} else if (this.level >= 8 && this.level <= 15) {
e = Randomizer.nextInt(13) + 7;
} else if (this.level >= 16 && this.level <= 24) {
e = Randomizer.nextInt(23) + 9;
} else {
e = Randomizer.nextInt(28) + 12;
}
this.setExp(this.exp + e);
}
}

View File

@ -0,0 +1,417 @@
package client.inventory;
import java.util.ArrayList;
import server.movement.StaticLifeMovement;
import server.movement.LifeMovementFragment;
import java.util.List;
import java.util.Iterator;
import server.MapleItemInformationProvider;
import java.sql.ResultSet;
import java.sql.PreparedStatement;
import java.sql.Connection;
import java.sql.SQLException;
import tools.FileoutputUtil;
import tools.FilePrinter;
import database.DBConPool;
import java.awt.Point;
import java.io.Serializable;
public class MaplePet implements Serializable {
private static final long serialVersionUID = 9179541993413738569L;
private String name;
private final int uniqueid;
private final int petitemid;
private int Fh;
private int stance;
private int limitedLife;
private Point pos;
private byte fullness;
private byte level;
private byte summoned;
private short inventorypos;
private short closeness;
private short flags;
private boolean changed;
private int[] excluded;
private MaplePet(final int petitemid, final int uniqueid) {
this.Fh = 0;
this.stance = 0;
this.limitedLife = 0;
this.fullness = 100;
this.level = 1;
this.summoned = 0;
this.inventorypos = 0;
this.closeness = 0;
this.flags = 0;
this.changed = false;
this.excluded = new int[10];
this.petitemid = petitemid;
this.uniqueid = uniqueid;
for (int i = 0; i < this.excluded.length; ++i) {
this.excluded[i] = 0;
}
}
private MaplePet(final int petitemid, final int uniqueid, final short inventorypos) {
this.Fh = 0;
this.stance = 0;
this.limitedLife = 0;
this.fullness = 100;
this.level = 1;
this.summoned = 0;
this.inventorypos = 0;
this.closeness = 0;
this.flags = 0;
this.changed = false;
this.excluded = new int[10];
this.petitemid = petitemid;
this.uniqueid = uniqueid;
this.inventorypos = inventorypos;
for (int i = 0; i < this.excluded.length; ++i) {
this.excluded[i] = 0;
}
}
public static final MaplePet loadFromDb(final int itemid, final int petid, final short inventorypos) {
final MaplePet ret = new MaplePet(itemid, petid, inventorypos);
try (final Connection con = (Connection) DBConPool.getInstance().getDataSource().getConnection();
final PreparedStatement ps = con.prepareStatement("SELECT * FROM pets WHERE petid = ?")) {
ps.setInt(1, petid);
try (final ResultSet rs = ps.executeQuery()) {
if (!rs.next()) {
rs.close();
ps.close();
return null;
}
ret.setName(rs.getString("name"));
ret.setCloseness((int) rs.getShort("closeness"));
ret.setLevel((int) rs.getByte("level"));
ret.setFullness((int) rs.getByte("fullness"));
ret.setLimitedLife(rs.getInt("seconds"));
ret.setFlags((int) rs.getShort("flags"));
final String[] list = rs.getString("excluded").split(",");
for (int i = 0; i < ret.excluded.length; ++i) {
ret.excluded[i] = Integer.parseInt(list[i]);
}
ret.changed = false;
rs.close();
}
ps.close();
con.close();
return ret;
} catch (SQLException ex) {
FilePrinter.printError("MaplePet.txt", (Throwable) ex, "loadFromDb");
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
return null;
}
}
public final void saveToDb() {
if (!this.changed) {
return;
}
try (final Connection con = (Connection) DBConPool.getInstance().getDataSource().getConnection();
final PreparedStatement ps = con.prepareStatement("UPDATE pets SET name = ?, level = ?, closeness = ?, fullness = ?, seconds = ?, flags = ?, excluded = ? WHERE petid = ?")) {
ps.setString(1, this.name);
ps.setByte(2, this.level);
ps.setShort(3, this.closeness);
ps.setByte(4, this.fullness);
ps.setInt(5, this.limitedLife);
ps.setShort(6, this.flags);
final StringBuilder list = new StringBuilder();
for (int i = 0; i < this.excluded.length; ++i) {
list.append(this.excluded[i]);
list.append(",");
}
final String newlist = list.toString();
ps.setString(7, newlist.substring(0, newlist.length() - 1));
ps.setInt(8, this.uniqueid);
ps.executeUpdate();
ps.close();
con.close();
this.changed = false;
} catch (SQLException ex) {
FilePrinter.printError("MaplePet.txt", (Throwable) ex, "saveToDb");
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
}
}
public static final MaplePet createPet(final int itemid, final int uniqueid) {
final MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
return createPet(itemid, ii.getName(itemid), 1, 0, 100, uniqueid, ii.getPetLimitLife(itemid), ii.getPetFlagInfo(itemid));
}
public static final MaplePet createPet(final int itemid, final String name, final int level, final int closeness, final int fullness, int uniqueid, final int limitedLife, final short flag) {
if (uniqueid <= -1) {
uniqueid = MapleInventoryIdentifier.getInstance();
}
try (final Connection con = (Connection) DBConPool.getInstance().getDataSource().getConnection();
final PreparedStatement pse = con.prepareStatement("INSERT INTO pets (petid, name, level, closeness, fullness, seconds, flags) VALUES (?, ?, ?, ?, ?, ?, ?)")) {
pse.setInt(1, uniqueid);
pse.setString(2, name);
pse.setByte(3, (byte) level);
pse.setShort(4, (short) closeness);
pse.setByte(5, (byte) fullness);
pse.setInt(6, limitedLife);
pse.setShort(7, flag);
pse.executeUpdate();
pse.close();
con.close();
} catch (SQLException ex) {
FilePrinter.printError("MaplePet.txt", (Throwable) ex, "createPet");
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
return null;
}
final MaplePet pet = new MaplePet(itemid, uniqueid);
pet.setName(name);
pet.setLevel(level);
pet.setFullness(fullness);
pet.setCloseness(closeness);
pet.setFlags((int) flag);
pet.setLimitedLife(limitedLife);
return pet;
}
public final String getName() {
if (this.name == null) {
this.setName(MapleItemInformationProvider.getInstance().getName(this.petitemid));
}
return this.name;
}
public final void setName(final String name) {
this.name = name;
this.changed = true;
}
public final boolean getSummoned() {
return this.summoned > 0;
}
public final byte getSummonedValue() {
return this.summoned;
}
public final void setSummoned(final int summoned) {
this.summoned = (byte) summoned;
}
public final short getInventoryPosition() {
return this.inventorypos;
}
public final void setInventoryPosition(final short inventorypos) {
this.inventorypos = inventorypos;
}
public int getUniqueId() {
return this.uniqueid;
}
public final short getCloseness() {
return this.closeness;
}
public final void setCloseness(int closeness) {
if (closeness >= Integer.MAX_VALUE || closeness <= 0) {
closeness = 1;
}
this.closeness = (short) closeness;
this.changed = true;
}
public final byte getLevel() {
return this.level;
}
public final void setLevel(final int level) {
this.level = (byte) level;
this.changed = true;
}
public final byte getFullness() {
return this.fullness;
}
public final void setFullness(final int fullness) {
this.fullness = (byte) fullness;
this.changed = true;
}
public final short getFlags() {
return this.flags;
}
public final void setFlags(final int fffh) {
this.flags = (short) fffh;
this.changed = true;
}
public final int getFh() {
return this.Fh;
}
public final void setFh(final int Fh) {
this.Fh = Fh;
}
public final Point getPos() {
return this.pos;
}
public final void setPos(final Point pos) {
this.pos = pos;
}
public final int getStance() {
return this.stance;
}
public final void setStance(final int stance) {
this.stance = stance;
}
public final int getPetItemId() {
return this.petitemid;
}
public final boolean canConsume(final int itemId) {
final MapleItemInformationProvider mii = MapleItemInformationProvider.getInstance();
final Iterator<Integer> iterator = mii.petsCanConsume(itemId).iterator();
while (iterator.hasNext()) {
final int petId = ((Integer) iterator.next()).intValue();
if (petId == this.petitemid) {
return true;
}
}
return false;
}
public final void updatePosition(final List<LifeMovementFragment> movement) {
for (final LifeMovementFragment move : movement) {
if (move instanceof StaticLifeMovement) {
final Point newPos = move.getPosition();
if (newPos == null) {
continue;
}
this.setPos(newPos);
this.setStance(((StaticLifeMovement) move).getNewstate());
}
}
}
public final int getSecondsLeft() {
return this.limitedLife;
}
public final void setLimitedLife(final int sl) {
this.limitedLife = sl;
this.changed = true;
}
public static void main(final String[] args) {
clearPet();
}
public static void clearPet() {
try (final Connection con = (Connection) DBConPool.getInstance().getDataSource().getConnection()) {
PreparedStatement ps = con.prepareStatement("SELECT * FROM pets");
final ResultSet rs = ps.executeQuery();
while (rs.next()) {
final int uid = rs.getInt("petid");
if (!ItemLoader.isExistsByUniqueid(uid)) {
ps = con.prepareStatement("DELETE FROM pets WHERE petid = ?");
ps.setInt(1, uid);
ps.executeUpdate();
System.err.println("宠物:" + rs.getString("name") + " petid: " + uid + " 不存在, 清理。");
}
}
rs.close();
ps.close();
con.close();
} catch (SQLException se) {
System.err.println("[MaplePet] 从数据库中加载宠物讯息出错");
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) se);
}
}
public void clearExcluded() {
for (int i = 0; i < this.excluded.length; ++i) {
this.excluded[i] = 0;
}
this.changed = true;
}
public List<Integer> getExcluded() {
final List list = new ArrayList();
for (int i = 0; i < this.excluded.length; ++i) {
if (this.excluded[i] > 0 && PetFlag.UNPICKABLE.check((int) this.flags)) {
list.add(Integer.valueOf(this.excluded[i]));
}
}
return (List<Integer>) list;
}
public void addExcluded(final int i, final int itemId) {
if (i < this.excluded.length) {
this.excluded[i] = itemId;
this.changed = true;
}
}
public enum PetFlag {
ITEM_PICKUP(1, 5190000, 5191000),
EXPAND_PICKUP(2, 5190002, 5191002),
AUTO_PICKUP(4, 5190003, 5191003),
UNPICKABLE(8, 5190005, -1),
LEFTOVER_PICKUP(16, 5190004, 5191004),
HP_CHARGE(32, 5190001, 5191001),
MP_CHARGE(64, 5190006, -1),
PET_BUFF(128, -1, -1),
PET_DRAW(256, 5190007, -1),
PET_DIALOGUE(512, 5190008, -1);
private final int i;
private final int item;
private final int remove;
private PetFlag(final int i, final int item, final int remove) {
this.i = i;
this.item = item;
this.remove = remove;
}
public final int getValue() {
return this.i;
}
public final boolean check(final int flag) {
return (flag & this.i) == this.i;
}
public static final PetFlag getByAddId(final int itemId) {
for (final PetFlag flag : values()) {
if (flag.item == itemId) {
return flag;
}
}
return null;
}
public static final PetFlag getByDelId(final int itemId) {
for (final PetFlag flag : values()) {
if (flag.remove == itemId) {
return flag;
}
}
return null;
}
}
}

View File

@ -0,0 +1,198 @@
package client.inventory;
import java.util.Comparator;
import server.MapleInventoryManipulator;
import com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException;
import client.MapleCharacter;
import java.sql.ResultSet;
import java.sql.PreparedStatement;
import java.sql.Connection;
import java.sql.SQLException;
import tools.FileoutputUtil;
import tools.FilePrinter;
import database.DBConPool;
import java.io.Serializable;
public class MapleRing implements Serializable {
private static final long serialVersionUID = 9179541993413738579L;
private final int ringId;
private final int ringId2;
private final int partnerId;
private final int itemId;
private String partnerName;
private boolean equipped;
private MapleRing(final int id, final int id2, final int partnerId, final int itemid, final String partnerName) {
this.equipped = false;
this.ringId = id;
this.ringId2 = id2;
this.partnerId = partnerId;
this.itemId = itemid;
this.partnerName = partnerName;
}
public static MapleRing loadFromDb(final int ringId) {
return loadFromDb(ringId, false);
}
public static MapleRing loadFromDb(final int ringId, final boolean equipped) {
try (final Connection con = (Connection) DBConPool.getInstance().getDataSource().getConnection();
final PreparedStatement ps = con.prepareStatement("SELECT * FROM rings WHERE ringId = ?")) {
ps.setInt(1, ringId);
MapleRing ret;
try (final ResultSet rs = ps.executeQuery()) {
ret = null;
if (rs.next()) {
ret = new MapleRing(ringId, rs.getInt("partnerRingId"), rs.getInt("partnerChrId"), rs.getInt("itemid"), rs.getString("partnerName"));
ret.setEquipped(equipped);
}
rs.close();
}
ps.close();
con.close();
return ret;
} catch (SQLException ex) {
FilePrinter.printError("MapleRing.txt", (Throwable) ex, "loadFromDB");
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
return null;
}
}
public static void addToDB(final int itemid, final MapleCharacter chr, final String player, final int id, final int[] ringId) throws SQLException {
try (final Connection con = (Connection) DBConPool.getInstance().getDataSource().getConnection()) {
PreparedStatement ps = con.prepareStatement("INSERT INTO rings (ringId, itemid, partnerChrId, partnerName, partnerRingId) VALUES (?, ?, ?, ?, ?)");
ps.setInt(1, ringId[0]);
ps.setInt(2, itemid);
ps.setInt(3, chr.getId());
ps.setString(4, chr.getName());
ps.setInt(5, ringId[1]);
ps.executeUpdate();
ps.close();
ps = con.prepareStatement("INSERT INTO rings (ringId, itemid, partnerChrId, partnerName, partnerRingId) VALUES (?, ?, ?, ?, ?)");
ps.setInt(1, ringId[1]);
ps.setInt(2, itemid);
ps.setInt(3, id);
ps.setString(4, player);
ps.setInt(5, ringId[0]);
ps.executeUpdate();
ps.close();
con.close();
} catch (SQLException ex) {
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
}
}
public static int createRing(final int itemid, final MapleCharacter partner1, final String partner2, final String msg, final int id2, final int sn) {
try {
if (partner1 == null) {
return -2;
}
if (id2 <= 0) {
return -1;
}
return makeRing(itemid, partner1, partner2, id2, msg, sn);
} catch (Exception ex) {
FilePrinter.printError("MapleRing.txt", (Throwable) ex, "createRing");
return 0;
}
}
public static int makeRing(final int itemid, final MapleCharacter partner1, final String partner2, final int id2, final String msg, final int sn) throws Exception {
final int[] ringID = {MapleInventoryIdentifier.getInstance(), MapleInventoryIdentifier.getInstance()};
try {
addToDB(itemid, partner1, partner2, id2, ringID);
} catch (MySQLIntegrityConstraintViolationException mslcve) {
return 0;
}
MapleInventoryManipulator.addRing(partner1, itemid, ringID[1], sn);
partner1.getCashInventory().gift(id2, partner1.getName(), msg, sn, ringID[0]);
return 1;
}
public int getRingId() {
return this.ringId;
}
public int getPartnerRingId() {
return this.ringId2;
}
public int getPartnerChrId() {
return this.partnerId;
}
public int getItemId() {
return this.itemId;
}
public boolean isEquipped() {
return this.equipped;
}
public void setEquipped(final boolean equipped) {
this.equipped = equipped;
}
public String getPartnerName() {
return this.partnerName;
}
public void setPartnerName(final String partnerName) {
this.partnerName = partnerName;
}
@Override
public boolean equals(final Object o) {
return o instanceof MapleRing && ((MapleRing) o).getRingId() == this.getRingId();
}
@Override
public int hashCode() {
int hash = 5;
hash = 53 * hash + this.ringId;
return hash;
}
public static void removeRingFromDB(final MapleCharacter player) {
try (final Connection con = (Connection) DBConPool.getInstance().getDataSource().getConnection()) {
PreparedStatement ps = con.prepareStatement("SELECT * FROM rings WHERE partnerChrId = ?");
ps.setInt(1, player.getId());
final ResultSet rs = ps.executeQuery();
if (!rs.next()) {
ps.close();
rs.close();
return;
}
final int otherId = rs.getInt("partnerRingId");
final int otherotherId = rs.getInt("ringId");
rs.close();
ps.close();
ps = con.prepareStatement("DELETE FROM rings WHERE ringId = ? OR ringId = ?");
ps.setInt(1, otherotherId);
ps.setInt(2, otherId);
ps.executeUpdate();
ps.close();
con.close();
} catch (SQLException ex) {
FilePrinter.printError("MapleRing.txt", (Throwable) ex, "removeRingFromDB");
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
}
}
public static class RingComparator implements Comparator<MapleRing>, Serializable {
@Override
public int compare(final MapleRing o1, final MapleRing o2) {
if (o1.ringId < o2.ringId) {
return -1;
}
if (o1.ringId == o2.ringId) {
return 0;
}
return 1;
}
}
}

View File

@ -0,0 +1,54 @@
package client.inventory;
public enum MapleWeaponType {
沒有武器(0.0f, 0),
闪亮克魯(1.2f, 25),
灵魂射手(1.7f, 15),
魔剑(1.3f, 20),
能量剑(1.3125f, 20),
幻兽棍棒(1.34f, 20),
单手剑(1.2f, 20),
单手斧(1.2f, 20),
单手棍(1.2f, 20),
短剑(1.3f, 20),
双刀(1.3f, 20),
手杖(1.3f, 20),
短杖(1.0f, 25),
长杖(1.0f, 25),
双手剑(1.34f, 20),
双手斧(1.34f, 20),
双手棍(1.34f, 20),
(1.49f, 20),
(1.49f, 20),
(1.3f, 15),
(1.35f, 15),
拳套(1.75f, 15),
指虎(1.7f, 20),
火枪(1.5f, 15),
双弩枪(1.3f, 15),
加農炮(1.5f, 15),
太刀(1.25f, 20),
扇子(1.35f, 25),
(1.49f, 20),
(1.34f, 20),
ESP限制器(1.0f, 20),
BIG_SWORD(1.3f, 15),
LONG_SWORD(1.3f, 15),
未知(0.0f, 0);
private final float damageMultiplier;
private final int baseMastery;
private MapleWeaponType(final float maxDamageMultiplier, final int baseMastery) {
this.damageMultiplier = maxDamageMultiplier;
this.baseMastery = baseMastery;
}
public final float getMaxDamageMultiplier() {
return this.damageMultiplier;
}
public final int getBaseMastery() {
return this.baseMastery;
}
}

View File

@ -0,0 +1,55 @@
package client.inventory;
import constants.GameConstants;
public class ModifyInventory {
private final int mode;
private IItem item;
private short oldPos;
public ModifyInventory(final int mode, final IItem item) {
this.mode = mode;
this.item = item.copy();
}
public ModifyInventory(final int mode, final IItem item, final short oldPos) {
this.mode = mode;
this.item = item.copy();
this.oldPos = oldPos;
}
public final int getMode() {
return this.mode;
}
public final int getInventoryType() {
return GameConstants.getInventoryType(this.item.getItemId()).getType();
}
public final short getPosition() {
return this.item.getPosition();
}
public final short getOldPosition() {
return this.oldPos;
}
public final short getQuantity() {
return this.item.getQuantity();
}
public final IItem getItem() {
return this.item;
}
public final void clear() {
this.item = null;
}
public static class Types {
public static final int ADD = 0;
public static final int UPDATE = 1;
public static final int MOVE = 2;
public static final int REMOVE = 3;
}
}

View File

@ -0,0 +1,170 @@
package client.inventory;
import java.util.ListIterator;
import java.sql.ResultSet;
import java.sql.PreparedStatement;
import java.sql.Connection;
import java.util.Map;
import java.sql.SQLException;
import tools.FileoutputUtil;
import handling.world.World.Broadcast;
import tools.MaplePacketCreator;
import server.MapleItemInformationProvider;
import tools.Quadra;
import database.DBConPool;
import java.util.LinkedList;
import java.util.HashMap;
import java.util.ArrayList;
import server.Timer.WorldTimer;
import tools.Triple;
import java.util.List;
public class OnlyID {
private static final OnlyID instance = new OnlyID();
private static List<Triple<Integer, Long, Long>> OnlyIDList = (List<Triple<Integer, Long, Long>>) new ArrayList();
public static OnlyID getInstance() {
return OnlyID.instance;
}
protected OnlyID() {
WorldTimer.getInstance().register((Runnable) new run(), 43200000L);
}
public static List<Triple<Integer, Long, Long>> getData() {
return OnlyID.OnlyIDList;
}
public static void addData(final int chrid, final long inventoryitemid, final long ItemOnlyID) {
OnlyID.OnlyIDList.add(new Triple(Integer.valueOf(chrid), Long.valueOf(inventoryitemid), Long.valueOf(ItemOnlyID)));
}
public static void removeData(final int chrid) {
OnlyID.OnlyIDList.remove(chrid);
}
public static void clearData() {
if (!OnlyID.OnlyIDList.isEmpty()) {
OnlyID.OnlyIDList.clear();
}
}
public void StartCheckings() {
StartChecking();
}
public static void StartChecking() {
if (!OnlyID.OnlyIDList.isEmpty()) {
OnlyID.OnlyIDList.clear();
}
StringBuilder chrs = new StringBuilder();
StringBuilder Sql = new StringBuilder();
final List<Quadra<Integer, Integer, Long, Integer>> equipOnlyIds = (List<Quadra<Integer, Integer, Long, Integer>>) new ArrayList();
final Map checkItems = new HashMap();
final List<Integer> all = (List<Integer>) new LinkedList();
final List<Integer> gm = (List<Integer>) new LinkedList();
try (final Connection con = (Connection) DBConPool.getInstance().getDataSource().getConnection()) {
PreparedStatement ps = con.prepareStatement("SELECT characterid FROM inventoryitems WHERE equipOnlyId > 0");
ResultSet rs = ps.executeQuery();
while (rs.next()) {
final int chr = rs.getInt("characterid");
if (chr != 0) {
all.add(Integer.valueOf(chr));
}
}
ps.close();
rs.close();
Sql = new StringBuilder();
if (!all.isEmpty()) {
Sql.append("and (id = ");
for (int i = 0; i < all.size(); ++i) {
Sql.append(all.get(i));
if (i < all.size() - 1) {
Sql.append(" OR id = ");
}
}
Sql.append(")");
}
ps = con.prepareStatement("SELECT id FROM characters WHERE gm > 0 " + Sql);
rs = ps.executeQuery();
while (rs.next()) {
final int chr = rs.getInt("id");
if (chr != 0) {
gm.add(Integer.valueOf(chr));
}
}
ps.close();
rs.close();
Sql = new StringBuilder();
if (!gm.isEmpty()) {
Sql.append("and characterid != ");
for (int i = 0; i < gm.size(); ++i) {
Sql.append(gm.get(i));
if (i < gm.size() - 1) {
Sql.append(" and characterid != ");
}
}
}
ps = con.prepareStatement("SELECT * FROM inventoryitems WHERE equipOnlyId > 0 " + Sql);
rs = ps.executeQuery();
while (rs.next()) {
final int chr = rs.getInt("characterid");
final int ac = rs.getInt("accountid");
final int itemId = rs.getInt("itemId");
final long equipOnlyId = rs.getLong("equipOnlyId");
final long inventoryitemid = rs.getLong("inventoryitemid");
if (equipOnlyId > 0L) {
if (checkItems.containsKey(Long.valueOf(equipOnlyId))) {
if (((Integer) checkItems.get(Long.valueOf(equipOnlyId))).intValue() != itemId) {
continue;
}
equipOnlyIds.add(new Quadra(Integer.valueOf(chr), Integer.valueOf(ac), Long.valueOf(equipOnlyId), Integer.valueOf(itemId)));
addData(chr, inventoryitemid, equipOnlyId);
} else {
checkItems.put(Long.valueOf(equipOnlyId), Integer.valueOf(itemId));
}
}
}
rs.close();
ps.close();
final ListIterator<Quadra<Integer, Integer, Long, Integer>> OnlyId = equipOnlyIds.listIterator();
while (OnlyId.hasNext()) {
chrs = new StringBuilder();
final Quadra<Integer, Integer, Long, Integer> Only = OnlyId.next();
final long itemonly = ((Long) Only.getThird()).longValue();
final int item = ((Integer) Only.getForth()).intValue();
ps = con.prepareStatement("SELECT characterid FROM inventoryitems WHERE equipOnlyId = " + itemonly);
rs = ps.executeQuery();
while (rs.next()) {
final int chr2 = rs.getInt("characterid");
if (chr2 != 0) {
chrs.append("角色 [").append(chr2).append("]");
}
}
rs.close();
ps.close();
String itemname = "null";
itemname = MapleItemInformationProvider.getInstance().getName(item);
final String msg = "发现复制,唯一ID [" + itemonly + "] " + chrs.toString() + " 物品[" + itemname + "](" + item + ")";
System.out.println(msg);
Broadcast.broadcastGMMessage(MaplePacketCreator.serverNotice(6, msg));
FileoutputUtil.logToFile("Hack/复制装备.txt", FileoutputUtil.CurrentReadable_TimeGMT() + " " + msg + "\r\n");
}
con.close();
} catch (SQLException ex) {
System.out.println("[EXCEPTION] 复制装备出现错误." + ex);
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
}
}
public static class run implements Runnable {
@Override
public void run() {
OnlyID.StartChecking();
}
}
}

View File

@ -0,0 +1,31 @@
package client.inventory;
public class PetCommand {
private final int petId;
private final int skillId;
private final int prob;
private final int inc;
public PetCommand(final int petId, final int skillId, final int prob, final int inc) {
this.petId = petId;
this.skillId = skillId;
this.prob = prob;
this.inc = inc;
}
public int getPetId() {
return this.petId;
}
public int getSkillId() {
return this.skillId;
}
public int getProbability() {
return this.prob;
}
public int getIncrease() {
return this.inc;
}
}

View File

@ -0,0 +1,47 @@
package client.inventory;
import java.util.HashMap;
import provider.MapleDataProviderFactory;
import provider.MapleData;
import provider.MapleDataTool;
import tools.Pair;
import java.util.Map;
import provider.MapleDataProvider;
public class PetDataFactory {
private static final MapleDataProvider dataRoot = MapleDataProviderFactory.getDataProvider("Item.wz");
private static final Map<Pair<Integer, Integer>, PetCommand> petCommands = new HashMap();
private static final Map<Integer, Integer> petHunger = new HashMap();
public static final PetCommand getPetCommand(final int petId, final int skillId) {
PetCommand ret = (PetCommand) PetDataFactory.petCommands.get(new Pair(Integer.valueOf(petId), Integer.valueOf(skillId)));
if (ret != null) {
return ret;
}
final MapleData skillData = PetDataFactory.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);
PetDataFactory.petCommands.put(new Pair(Integer.valueOf(petId), Integer.valueOf(skillId)), ret);
return ret;
}
public static final int getHunger(final int petId) {
Integer ret = (Integer) PetDataFactory.petHunger.get(Integer.valueOf(petId));
if (ret != null) {
return ret.intValue();
}
final MapleData hungerData = PetDataFactory.dataRoot.getData("Pet/" + petId + ".img").getChildByPath("info/hungry");
ret = Integer.valueOf(MapleDataTool.getInt(hungerData, 1));
PetDataFactory.petHunger.put(Integer.valueOf(petId), ret);
return ret.intValue();
}
}

View File

@ -0,0 +1,318 @@
package client.messages;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import client.messages.commands.CommandExecute;
import java.lang.reflect.Modifier;
import client.messages.commands.GodCommand;
import client.messages.commands.AdminCommand;
import client.messages.commands.GMCommand;
import client.messages.commands.InternCommand;
import client.messages.commands.SkilledCommand;
import client.messages.commands.PracticerCommand;
import client.messages.commands.PlayerCommand;
import java.sql.PreparedStatement;
import java.sql.Connection;
import java.sql.SQLException;
import tools.FilePrinter;
import database.DBConPool;
import client.MapleCharacter;
import handling.world.World.Broadcast;
import tools.MaplePacketCreator;
import constants.PiPiConfig;
import java.util.LinkedList;
import tools.FileoutputUtil;
import constants.ServerConstants.PlayerGMRank;
import constants.ServerConstants.CommandType;
import java.util.Iterator;
import client.MapleClient;
import java.util.List;
import java.util.ArrayList;
import client.messages.commands.CommandObject;
import java.util.HashMap;
public class CommandProcessor {
private static final HashMap<String, CommandObject> commands = new HashMap();
private static final HashMap<Integer, ArrayList<String>> NormalCommandList = new HashMap();
private static final HashMap<Integer, ArrayList<String>> VipCommandList = new HashMap();
private static final List<String> showcommands = new LinkedList();
public static void dropHelp(final MapleClient c, final int type) {
final StringBuilder sb = new StringBuilder("指令列表:\r\n ");
HashMap<Integer, ArrayList<String>> commandList = (HashMap<Integer, ArrayList<String>>) new HashMap();
int check = 0;
if (type == 0) {
commandList = CommandProcessor.NormalCommandList;
check = c.getPlayer().getGMLevel();
}
for (int i = 0; i <= check; ++i) {
if (commandList.containsKey(Integer.valueOf(i))) {
sb.append((type == 1) ? "VIP" : "").append("权限等级: ").append(i).append("\r\n");
for (final String s : commandList.get(Integer.valueOf(i))) {
final CommandObject co = (CommandObject) CommandProcessor.commands.get(s);
sb.append(co.getMessage());
sb.append(" \r\n");
}
}
}
c.getPlayer().dropNPC(sb.toString());
}
private static void sendDisplayMessage(final MapleClient c, final String msg, final CommandType type) {
if (c.getPlayer() == null) {
return;
}
switch (type) {
case NORMAL: {
c.getPlayer().dropMessage(6, msg);
break;
}
case TRADE: {
c.getPlayer().dropMessage(-2, "错误 : " + msg);
break;
}
}
}
public static boolean processCommand(final MapleClient c, final String line, final CommandType type) {
if (c != null) {
final char commandPrefix = line.charAt(0);
for (final PlayerGMRank prefix : PlayerGMRank.values()) {
if (line.startsWith(String.valueOf(prefix.getCommandPrefix() + prefix.getCommandPrefix()))) {
return false;
}
}
if (commandPrefix == PlayerGMRank.普通玩家.getCommandPrefix()) {
final String[] splitted = line.split(" ");
splitted[0] = splitted[0].toLowerCase();
final CommandObject co = (CommandObject) CommandProcessor.commands.get(splitted[0]);
if (co == null || co.getType() != type) {
sendDisplayMessage(c, "沒有这个指令,可以使用 @help 来查看指令.", type);
return true;
}
try {
final boolean ret = co.execute(c, splitted);
if (!ret) {
c.getPlayer().dropMessage("指令错误,用法: " + co.getMessage());
}
} catch (Exception e) {
sendDisplayMessage(c, "有错误.", type);
if (c.getPlayer().isGM()) {
sendDisplayMessage(c, "错误: " + e, type);
}
FileoutputUtil.outputFileError("logs\\Except\\Log_Command_Except.txt", (Throwable) e);
FileoutputUtil.logToFile("logs\\Except\\Log_Command_Except.txt", FileoutputUtil.NowTime() + c.getPlayer().getName() + "(" + c.getPlayer().getId() + ")使用了指令 " + line + " ---在地图「" + c.getPlayer().getMapId() + "」频道:" + c.getChannel() + " \r\n");
}
return true;
} else if (c.getPlayer().getGMLevel() > PlayerGMRank.普通玩家.getLevel()) {
final String[] splitted = line.split(" ");
splitted[0] = splitted[0].toLowerCase();
final List<String> show = (List<String>) new LinkedList();
for (final String com : CommandProcessor.showcommands) {
if (com.contains((CharSequence) splitted[0])) {
show.add(com);
}
}
if (show.isEmpty()) {
final StringBuilder sb = new StringBuilder();
final int iplength = splitted[0].length();
for (final String com2 : CommandProcessor.showcommands) {
final int sclength = com2.length();
final String[] next = new String[sclength];
for (int i = 0; i < next.length; ++i) {
next[i] = "false";
}
if (iplength == sclength) {
for (int i = 0; i < sclength; ++i) {
final String st = com2.substring(i, i + 1);
for (int r = 0; r < iplength; ++r) {
final String it = splitted[0].substring(r, r + 1);
if (st.equals(it)) {
next[i] = "true";
}
}
}
boolean last = true;
for (int j = 0; j < next.length; ++j) {
if ("false".equals(next[j])) {
last = false;
}
}
if (!last || !show.isEmpty()) {
continue;
}
show.add(com2);
}
}
}
if (show.size() == 1 && !splitted[0].equals(show.get(0))) {
sendDisplayMessage(c, "自动識別关联指令[" + (String) show.get(0) + "].", type);
splitted[0] = (String) show.get(0);
}
if (line.charAt(0) == '!') {
final CommandObject co2 = (CommandObject) CommandProcessor.commands.get(splitted[0]);
if (co2 == null || co2.getType() != type) {
if (splitted[0].equals(line.charAt(0) + "help")) {
dropHelp(c, 0);
return true;
}
sendDisplayMessage(c, "沒有这个指令.", type);
return true;
} else {
boolean CanUseCommand = false;
if (c.getPlayer().getGMLevel() >= co2.getReqGMLevel()) {
CanUseCommand = true;
}
if (!CanUseCommand) {
sendDisplayMessage(c, "你沒有权限可以使用指令.", type);
return true;
}
if (PiPiConfig.getCommandLock() && !c.getPlayer().isGod()) {
sendDisplayMessage(c, "目前无法使用指令.", type);
return true;
}
if (c.getPlayer() != null) {
boolean ret2 = false;
try {
ret2 = co2.execute(c, splitted);
if (ret2) {
logGMCommandToDB(c.getPlayer(), line);
FileoutputUtil.logToFile("logs/Data/管理员命令.txt", "\r\n " + FileoutputUtil.NowTime() + " IP: " + c.getSession().remoteAddress().toString().split(":")[0] + " 账号: " + c.getAccountName() + " 玩家: " + c.getPlayer().getName() + " 使用管理员命令:" + line);
ShowMsg(c, line, type);
} else {
c.getPlayer().dropMessage("指令错误,用法: " + co2.getMessage());
}
} catch (Exception e2) {
FileoutputUtil.outputFileError("logs\\Except\\Log_Command_Except.txt", (Throwable) e2);
String output = FileoutputUtil.NowTime();
if (c != null && c.getPlayer() != null) {
output = output + c.getPlayer().getName() + "(" + c.getPlayer().getId() + ")使用了指令 " + line + " ---在地图「" + c.getPlayer().getMapId() + "」频道:" + c.getChannel();
}
FileoutputUtil.logToFile("logs\\Except\\Log_Command_Except.txt", output + " \r\n");
}
return true;
}
}
}
}
}
return false;
}
private static void ShowMsg(final MapleClient c, final String line, final CommandType type) {
if (c.getPlayer() != null) {
if (!c.getPlayer().isGod() && !line.toLowerCase().startsWith("!cngm")) {
Broadcast.broadcastGMMessage(MaplePacketCreator.serverNotice(6, "[GM密语] " + c.getPlayer().getName() + "(" + c.getPlayer().getId() + ")使用了指令 " + line + " ---在地图「" + c.getPlayer().getMapId() + "」频道:" + c.getChannel()));
}
if (c.getPlayer().getGMLevel() == 5) {
System.out.println("<超级管理员> " + c.getPlayer().getName() + " 使用了指令: " + line);
} else if (c.getPlayer().getGMLevel() == 4) {
System.out.println("<领导者> " + c.getPlayer().getName() + " 使用了指令: " + line);
} else if (c.getPlayer().getGMLevel() == 3) {
System.out.println("<巡逻者> " + c.getPlayer().getName() + " 使用了指令: " + line);
} else if (c.getPlayer().getGMLevel() == 2) {
System.out.println("<老实习生> " + c.getPlayer().getName() + " 使用了指令: " + line);
} else if (c.getPlayer().getGMLevel() == 1) {
System.out.println("<新实习生> " + c.getPlayer().getName() + " 使用了指令: " + line);
} else if (c.getPlayer().getGMLevel() != 100) {
sendDisplayMessage(c, "你沒有权限可以使用指令.", type);
}
}
}
private static void logGMCommandToDB(final MapleCharacter player, final String command) {
if (player == null) {
return;
}
Connection con = null;
PreparedStatement ps = null;
try {
con = (Connection) DBConPool.getInstance().getDataSource().getConnection();
ps = con.prepareStatement("INSERT INTO gmlog (cid, command, mapid) VALUES (?, ?, ?)");
ps.setInt(1, player.getId());
ps.setString(2, command);
ps.setInt(3, player.getMap().getId());
ps.executeUpdate();
ps.close();
con.close();
} catch (SQLException ex) {
FilePrinter.printError("CommandProccessor.txt", (Throwable) ex, "logGMCommandToDB");
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
try {
if (ps != null) {
ps.close();
}
if (con != null) {
con.close();
}
} catch (SQLException e) {
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) e);
}
} finally {
try {
if (ps != null) {
ps.close();
}
if (con != null) {
con.close();
}
} catch (SQLException e2) {
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) e2);
}
}
}
private static void DoNormalCommand() {
final Class[] array;
final Class<?>[] CommandFiles = (Class<?>[]) (array = new Class[]{PlayerCommand.class, PracticerCommand.class, SkilledCommand.class, InternCommand.class, GMCommand.class, AdminCommand.class, GodCommand.class});
for (final Class<?> clasz : array) {
try {
final PlayerGMRank rankNeeded = (PlayerGMRank) clasz.getMethod("getPlayerLevelRequired", new Class[0]).invoke(null, (Object[]) null);
final Class<?>[] commandClasses = clasz.getDeclaredClasses();
final ArrayList<String> cL = (ArrayList<String>) new ArrayList();
for (final Class<?> c : commandClasses) {
try {
if (!Modifier.isAbstract(c.getModifiers()) && !c.isSynthetic()) {
final Object o = c.newInstance();
boolean enabled;
try {
enabled = c.getDeclaredField("enabled").getBoolean(c.getDeclaredField("enabled"));
} catch (NoSuchFieldException ex3) {
enabled = true;
}
if (o instanceof CommandExecute && enabled) {
cL.add(rankNeeded.getCommandPrefix() + c.getSimpleName().toLowerCase());
CommandProcessor.commands.put(rankNeeded.getCommandPrefix() + c.getSimpleName().toLowerCase(), new CommandObject(rankNeeded.getCommandPrefix() + c.getSimpleName().toLowerCase(), (CommandExecute) o, rankNeeded.getLevel()));
CommandProcessor.showcommands.add(rankNeeded.getCommandPrefix() + c.getSimpleName().toLowerCase());
}
}
} catch (InstantiationException | IllegalAccessException | SecurityException |
IllegalArgumentException ex6) {
FilePrinter.printError("CommandProccessor.txt", (Throwable) ex6);
}
}
Collections.sort((List<String>) cL);
CommandProcessor.NormalCommandList.put(Integer.valueOf(rankNeeded.getLevel()), cL);
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException |
InvocationTargetException ex7) {
FilePrinter.printError("CommandProccessor.txt", (Throwable) ex7);
}
}
}
static {
DoNormalCommand();
}
}

View File

@ -0,0 +1,75 @@
package client.messages;
import tools.StringUtil;
public class CommandProcessorUtil {
public static String joinAfterString(final String[] splitted, final String str) {
for (int i = 1; i < splitted.length; ++i) {
if (splitted[i].equalsIgnoreCase(str) && i + 1 < splitted.length) {
return StringUtil.joinStringFrom(splitted, i + 1);
}
}
return null;
}
public static int getOptionalIntArg(final String[] splitted, final int position, final int def) {
if (splitted.length > position) {
try {
return Integer.parseInt(splitted[position]);
} catch (NumberFormatException nfe) {
return def;
}
}
return def;
}
public static String getNamedArg(final String[] splitted, final int startpos, final String name) {
for (int i = startpos; i < splitted.length; ++i) {
if (splitted[i].equalsIgnoreCase(name) && i + 1 < splitted.length) {
return splitted[i + 1];
}
}
return null;
}
public static Long getNamedLongArg(final String[] splitted, final int startpos, final String name) {
final String arg = getNamedArg(splitted, startpos, name);
if (arg != null) {
try {
return Long.valueOf(Long.parseLong(arg));
} catch (NumberFormatException ex) {
}
}
return null;
}
public static Integer getNamedIntArg(final String[] splitted, final int startpos, final String name) {
final String arg = getNamedArg(splitted, startpos, name);
if (arg != null) {
try {
return Integer.valueOf(Integer.parseInt(arg));
} catch (NumberFormatException ex) {
}
}
return null;
}
public static int getNamedIntArg(final String[] splitted, final int startpos, final String name, final int def) {
final Integer ret = getNamedIntArg(splitted, startpos, name);
if (ret == null) {
return def;
}
return ret.intValue();
}
public static Double getNamedDoubleArg(final String[] splitted, final int startpos, final String name) {
final String arg = getNamedArg(splitted, startpos, name);
if (arg != null) {
try {
return Double.valueOf(Double.parseDouble(arg));
} catch (NumberFormatException ex) {
}
}
return null;
}
}

View File

@ -0,0 +1,70 @@
package client.messages;
import java.util.List;
import java.util.Collections;
import tools.FilePrinter;
import client.messages.commands.ConsoleCommandExecute;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import client.messages.commands.ConsoleCommand;
import client.messages.commands.ConsoleCommandObject;
import java.util.HashMap;
public class ConsoleCommandProcessor {
private static final HashMap<String, ConsoleCommandObject> commands;
private static void sendDisplayMessage(final String msg) {
System.err.println("[sendDisplayMessage]错误:" + msg);
}
public static boolean processCommand(final String line) {
final String[] splitted = line.split(" ");
splitted[0] = splitted[0].toLowerCase();
final ConsoleCommandObject co = (ConsoleCommandObject) ConsoleCommandProcessor.commands.get(splitted[0]);
if (co == null) {
sendDisplayMessage("沒有这个指令.");
return true;
}
final int ret = co.execute(splitted);
return true;
}
static {
commands = new HashMap();
final Class[] array;
final Class<?>[] CommandFiles = (Class<?>[]) (array = new Class[]{ConsoleCommand.class});
for (final Class<?> clasz : array) {
try {
final Class<?>[] a = clasz.getDeclaredClasses();
final ArrayList<String> cL = (ArrayList<String>) new ArrayList();
for (final Class<?> c : a) {
try {
if (!Modifier.isAbstract(c.getModifiers()) && !c.isSynthetic()) {
final Object o = c.newInstance();
boolean enabled;
try {
enabled = c.getDeclaredField("enabled").getBoolean(c.getDeclaredField("enabled"));
} catch (NoSuchFieldException ex3) {
enabled = true;
}
if (o instanceof ConsoleCommandExecute && enabled) {
cL.add(c.getSimpleName().toLowerCase());
commands.put(c.getSimpleName().toLowerCase(), new ConsoleCommandObject(c.getSimpleName().toLowerCase(), (ConsoleCommandExecute) o));
}
}
} catch (InstantiationException | IllegalAccessException | SecurityException |
IllegalArgumentException ex5) {
FilePrinter.printError("ConsoleCommandProcessor.txt", (Throwable) ex5);
}
}
Collections.sort((List<String>) cL);
} catch (Exception ex2) {
FilePrinter.printError("ConsoleCommandProcessor.txt", (Throwable) ex2);
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,26 @@
package client.messages.commands;
import constants.ServerConstants.CommandType;
import client.MapleClient;
public abstract class CommandExecute {
public abstract boolean execute(final MapleClient p0, final String[] p1);
public CommandType getType() {
return CommandType.NORMAL;
}
public abstract String getMessage();
enum ReturnValue {
DONT_LOG,
LOG;
}
public abstract static class TradeExecute extends CommandExecute {
@Override
public CommandType getType() {
return CommandType.TRADE;
}
}
}

View File

@ -0,0 +1,32 @@
package client.messages.commands;
import constants.ServerConstants.CommandType;
import client.MapleClient;
public class CommandObject {
private final String command;
private final int gmLevelReq;
private final CommandExecute exe;
public CommandObject(final String com, final CommandExecute c, final int gmLevel) {
this.command = com;
this.exe = c;
this.gmLevelReq = gmLevel;
}
public boolean execute(final MapleClient c, final String[] splitted) {
return this.exe.execute(c, splitted);
}
public CommandType getType() {
return this.exe.getType();
}
public int getReqGMLevel() {
return this.gmLevelReq;
}
public String getMessage() {
return (this.command != null) ? this.exe.getMessage() : "";
}
}

View File

@ -0,0 +1,4 @@
package client.messages.commands;
public class ConsoleCommand {
}

View File

@ -0,0 +1,5 @@
package client.messages.commands;
public abstract class ConsoleCommandExecute {
public abstract int execute(final String[] p0);
}

View File

@ -0,0 +1,15 @@
package client.messages.commands;
public class ConsoleCommandObject {
private final String command;
private final ConsoleCommandExecute exe;
public ConsoleCommandObject(final String com, final ConsoleCommandExecute c) {
this.command = com;
this.exe = c;
}
public int execute(final String[] splitted) {
return this.exe.execute(splitted);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,342 @@
package client.messages.commands;
import constants.PiPiConfig;
import client.SkillFactory;
import client.MapleCharacter;
import client.MapleStat;
import client.MapleClient;
import constants.ServerConstants.PlayerGMRank;
public class GodCommand {
public static PlayerGMRank getPlayerLevelRequired() {
return PlayerGMRank.;
}
public static class MinStats extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
final MapleCharacter player = c.getPlayer();
player.getStat().setHp(50);
player.getStat().setMp(50);
player.getStat().setMaxHp((short) 50);
player.getStat().setMaxMp((short) 50);
player.getStat().setStr((short) 4);
player.getStat().setDex((short) 4);
player.getStat().setInt((short) 4);
player.getStat().setLuk((short) 4);
player.setLevel((short) 10);
player.updateSingleStat(MapleStat.HP, 50);
player.updateSingleStat(MapleStat.MP, 50);
player.updateSingleStat(MapleStat.MAXHP, 50);
player.updateSingleStat(MapleStat.MAXMP, 50);
player.updateSingleStat(MapleStat.STR, 4);
player.updateSingleStat(MapleStat.DEX, 4);
player.updateSingleStat(MapleStat.INT, 4);
player.updateSingleStat(MapleStat.LUK, 4);
player.updateSingleStat(MapleStat.LEVEL, 10);
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!MinStats - 预设属性").toString();
}
}
public static class Buff extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
final MapleCharacter player = c.getPlayer();
SkillFactory.getSkill(9001002).getEffect(1).applyTo(player);
SkillFactory.getSkill(9001003).getEffect(1).applyTo(player);
SkillFactory.getSkill(9001008).getEffect(1).applyTo(player);
SkillFactory.getSkill(9001001).getEffect(1).applyTo(player);
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!Buff - 施放管理BUFF").toString();
}
}
public static class Maxstats extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
final MapleCharacter player = c.getPlayer();
player.getStat().setHp(30000);
player.getStat().setMp(30000);
player.getStat().setMaxHp((short) 30000);
player.getStat().setMaxMp((short) 30000);
player.getStat().setStr((short) 32767);
player.getStat().setDex((short) 32767);
player.getStat().setInt((short) 32767);
player.getStat().setLuk((short) 32767);
player.setLevel((short) 199);
player.updateSingleStat(MapleStat.HP, 30000);
player.updateSingleStat(MapleStat.MP, 30000);
player.updateSingleStat(MapleStat.MAXHP, 30000);
player.updateSingleStat(MapleStat.MAXMP, 30000);
player.updateSingleStat(MapleStat.STR, 32767);
player.updateSingleStat(MapleStat.DEX, 32767);
player.updateSingleStat(MapleStat.INT, 32767);
player.updateSingleStat(MapleStat.LUK, 32767);
player.updateSingleStat(MapleStat.LEVEL, 199);
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!Maxstats - 满属性").toString();
}
}
public static class BanCommand extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
PiPiConfig.setCommandLock(!PiPiConfig.getCommandLock());
c.getPlayer().dropMessage("指令封锁: " + PiPiConfig.getCommandLock());
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!BanCommand - 封锁指令").toString();
}
}
public static class hair extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
final MapleCharacter player = c.getPlayer();
int id = 0;
if (splitted.length < 2) {
return false;
}
id = Integer.parseInt(splitted[1]);
player.setHair(id);
player.updateSingleStat(MapleStat.HAIR, id);
player.dropMessage(5, "您当前发型的ID已被改为: " + id);
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!Hair <发型代码> - 修改发型").toString();
}
}
public static class face extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
final MapleCharacter player = c.getPlayer();
int id = 0;
if (splitted.length < 2) {
return false;
}
id = Integer.parseInt(splitted[1]);
player.setFace(id);
player.updateSingleStat(MapleStat.FACE, id);
player.dropMessage(5, "您当前脸型的ID已被改为: " + id);
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!Face <脸型代码> - 修改脸型").toString();
}
}
public static class Str extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
final MapleCharacter player = c.getPlayer();
int id = 0;
if (splitted.length < 2) {
return false;
}
id = Integer.parseInt(splitted[1]);
player.setStr(id);
player.updateSingleStat(MapleStat.STR, id);
player.dropMessage(5, "您当前力量已被改为: " + id);
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!Str <能力值> - 修改能力值").toString();
}
}
public static class Int extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
final MapleCharacter player = c.getPlayer();
int id = 0;
if (splitted.length < 2) {
return false;
}
id = Integer.parseInt(splitted[1]);
player.setInt(id);
player.updateSingleStat(MapleStat.INT, id);
player.dropMessage(5, "您当前智力已被改为: " + id);
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!Int <能力值> - 修改能力值").toString();
}
}
public static class Luk extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
final MapleCharacter player = c.getPlayer();
int id = 0;
if (splitted.length < 2) {
return false;
}
id = Integer.parseInt(splitted[1]);
player.setLuk(id);
player.updateSingleStat(MapleStat.LUK, id);
player.dropMessage(5, "您当前幸运已被改为: " + id);
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!Luk <能力值> - 修改能力值").toString();
}
}
public static class Dex extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
final MapleCharacter player = c.getPlayer();
int id = 0;
if (splitted.length < 2) {
return false;
}
id = Integer.parseInt(splitted[1]);
player.setDex(id);
player.updateSingleStat(MapleStat.DEX, id);
player.dropMessage(5, "您当前敏捷已被改为: " + id);
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!Luk <能力值> - 修改能力值").toString();
}
}
public static class HP extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
final MapleCharacter player = c.getPlayer();
int id = 0;
if (splitted.length < 2) {
return false;
}
id = Integer.parseInt(splitted[1]);
player.setHp(id);
player.setMaxHp(id);
player.updateSingleStat(MapleStat.HP, id);
player.updateSingleStat(MapleStat.MAXHP, id);
player.dropMessage(5, "您当前HP已被改为: " + id);
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!HP <能力值> - 修改能力值").toString();
}
}
public static class MP extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
final MapleCharacter player = c.getPlayer();
int id = 0;
if (splitted.length < 2) {
return false;
}
id = Integer.parseInt(splitted[1]);
player.setMp(id);
player.setMaxMp(id);
player.updateSingleStat(MapleStat.MP, id);
player.updateSingleStat(MapleStat.MAXMP, id);
player.dropMessage(5, "您当前MP已被改为: " + id);
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!MP <能力值> - 修改能力值").toString();
}
}
public static class Job extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
int jobid = 0;
try {
jobid = Integer.parseInt(splitted[1]);
} catch (Exception ex) {
return false;
}
c.getPlayer().changeJob(jobid);
c.getPlayer().dispelDebuffs();
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!job <职业代码> - 更换职业").toString();
}
}
public static class Level extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
if (splitted.length < 2) {
return false;
}
int level = c.getPlayer().getLevel();
try {
level = Short.parseShort(splitted[1]);
} catch (Exception ex) {
}
c.getPlayer().setLevel((short) level);
c.getPlayer().updateSingleStat(MapleStat.LEVEL, level);
c.getPlayer().setExp(0);
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!Level <等级> - 改变等级").toString();
}
}
public static class 无敌 extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
final MapleCharacter player = c.getPlayer();
if (player.isInvincible()) {
player.setInvincible(false);
player.dropMessage(6, "无敌模式已关闭。");
} else {
player.setInvincible(true);
player.dropMessage(6, "无敌模式已开启。");
}
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!无敌 - 无敌").toString();
}
}
}

View File

@ -0,0 +1,731 @@
package client.messages.commands;
import client.MapleStat;
import java.util.Map;
import client.MapleCharacterUtil;
import java.util.List;
import handling.world.CheaterData;
import handling.world.World;
import server.MaplePortal;
import server.maps.MapleMap;
import java.util.Iterator;
import tools.StringUtil;
import handling.channel.ChannelServer;
import handling.world.World.Find;
import java.sql.ResultSet;
import java.sql.PreparedStatement;
import java.sql.Connection;
import tools.FileoutputUtil;
import tools.FilePrinter;
import database.DBConPool;
import client.MapleCharacter;
import client.MapleClient;
import constants.ServerConstants.PlayerGMRank;
public class InternCommand {
public static PlayerGMRank getPlayerLevelRequired() {
return PlayerGMRank.巡逻者;
}
public static class 发勋章 extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
if (splitted.length < 2) {
return false;
}
final String playername = splitted[1];
final int playerid = MapleCharacter.getCharacterIdByName(playername);
if (playerid == -1) {
c.getPlayer().dropMessage("玩家[" + playername + "]不存在于资料库內。");
return true;
}
final MapleCharacter victim = MapleCharacter.getCharacterById(playerid);
final int accountid = victim.getAccountID();
final int id = this.createPlayer(accountid, playerid, playername);
if (id < 0) {
if (id == -3) {
c.getPlayer().dropMessage("账号ID[" + accountid + "]已经在领取勋章清单內。");
} else if (id == -2) {
c.getPlayer().dropMessage("玩家[" + playername + "]已经在领取勋章清单內。");
} else if (id == -1) {
c.getPlayer().dropMessage("发生未知的错误。");
}
return true;
}
c.getPlayer().dropMessage("玩家[" + playername + "]已经成功添加到领取勋章清单內(编号" + id + ")。");
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!发勋章 <玩家名称> - 将勋章领取名单添加玩家").toString();
}
public int createPlayer(final int accountid, final int id, final String name) {
try (final Connection con = (Connection) DBConPool.getInstance().getDataSource().getConnection()) {
PreparedStatement ps = con.prepareStatement("SELECT id FROM RCmedals WHERE name = ?");
ps.setString(1, name);
ResultSet rs = ps.executeQuery();
if (rs.first()) {
rs.close();
ps.close();
return -2;
}
rs.close();
ps.close();
ps = con.prepareStatement("SELECT accountid FROM RCmedals WHERE accountid = ?");
ps.setInt(1, accountid);
rs = ps.executeQuery();
if (rs.first()) {
rs.close();
ps.close();
return -3;
}
rs.close();
ps.close();
ps = con.prepareStatement("INSERT INTO RCmedals (`accountid`,`id`, `name`, `amount`) VALUES (?, ?, ?, ?)", 1);
ps.setInt(1, accountid);
ps.setInt(2, id);
ps.setString(3, name);
ps.setInt(4, 1);
ps.execute();
rs = ps.getGeneratedKeys();
int ret = 0;
if (rs.next()) {
ret = rs.getInt(1);
}
rs.close();
ps.close();
con.close();
return ret;
} catch (Exception ex) {
FilePrinter.printError("InternCommand.txt", (Throwable) ex, "createPlayer(" + name + ")");
FileoutputUtil.outError("logs/资料库异常.txt", (Throwable) ex);
return -1;
}
}
}
public static class Mute extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
if (splitted.length < 2) {
return false;
}
String name = "";
try {
name = splitted[1];
} catch (Exception ex) {
}
final int ch = Find.findChannel(name);
if (ch > 0) {
final MapleCharacter victim = ChannelServer.getInstance(ch).getPlayerStorage().getCharacterByName(splitted[1]);
victim.canTalk(!victim.getCanTalk());
c.getPlayer().dropMessage("玩家[" + victim.getName() + "] 目前已经" + (victim.getCanTalk() ? "可以说话" : "闭嘴"));
} else {
c.getPlayer().dropMessage("玩家[" + splitted[1] + "] 目前不在线上或是正在购物商城");
}
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!Mute \t玩家名称 - 让玩家闭嘴或可以说话").toString();
}
}
public static class MuteMap extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
for (final MapleCharacter chr : c.getPlayer().getMap().getCharactersThreadsafe()) {
chr.canTalk(!chr.getCanTalk());
final StringBuilder ret = new StringBuilder();
ret.append(" 角色昵称 ");
ret.append(StringUtil.getRightPaddedStr(chr.getName(), ' ', 13));
ret.append(" ID: ");
ret.append(StringUtil.getRightPaddedStr(chr.getId() + "", ' ', 5));
ret.append(" 目前已经: ");
ret.append(chr.getCanTalk() ? "可以说话" : "闭嘴");
c.getPlayer().dropMessage(ret.toString());
}
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!MuteMap \t- 让地图玩家闭嘴或可以说话").toString();
}
}
public static class HellBan extends client.messages.commands.PracticerCommand.Ban {
public HellBan() {
this.hellban = true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!hellban <玩家名称> <原因> - hellban").toString();
}
}
public static class CC extends ChangeChannel {
@Override
public String getMessage() {
return new StringBuilder().append("!cc <频道> - 更换频道").toString();
}
}
public static class ChangeChannel extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
if (splitted.length < 2) {
return false;
}
final int cc = Integer.parseInt(splitted[1]);
if (c.getChannel() != cc) {
c.getPlayer().changeChannel(cc);
} else {
c.getPlayer().dropMessage(5, "请输入正确的频道。");
}
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!changechannel <频道> - 更换频道").toString();
}
}
public static class 角色讯息 extends spy {
}
public static class spy extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
if (splitted.length < 2) {
return false;
}
final String name = splitted[1];
final MapleCharacter victim = MapleCharacter.getCharacterByName(name);
final int ch = Find.findChannel(name);
if (victim != null) {
if (victim.getGMLevel() > c.getPlayer().getGMLevel()) {
c.getPlayer().dropMessage(5, "你不能查看比你高权限的人!");
} else {
int mesoInStorage = 0;
try {
if (victim.getStorage() != null) {
mesoInStorage = victim.getStorage().getMeso();
}
} catch (Exception ex) {
}
c.getPlayer().dropMessage(5, "此玩家状态:");
c.getPlayer().dropMessage(5, "玩家名称: " + victim.getName() + " 玩家编号: " + victim.getId() + " 账号: " + victim.getClient().getAccountName() + " 账号ID: " + victim.getAccountID());
c.getPlayer().dropMessage(5, "玩家权限: " + victim.getGMLevel() + " 等级: " + (int) victim.getLevel() + " 职业: " + (int) victim.getJob() + " 名声: " + (int) victim.getFame());
c.getPlayer().dropMessage(5, "地图: " + victim.getMapId() + " - " + victim.getMap().getMapName());
c.getPlayer().dropMessage(5, "目前HP: " + (int) victim.getStat().getHp() + " 目前MP: " + (int) victim.getStat().getMp());
c.getPlayer().dropMessage(5, "最大HP: " + (int) victim.getStat().getMaxHp() + " 最大MP: " + (int) victim.getStat().getMaxMp());
c.getPlayer().dropMessage(5, "力量: " + (int) victim.getStat().getStr() + " || 敏捷: " + (int) victim.getStat().getDex() + " || 智力: " + (int) victim.getStat().getInt() + " || 幸运: " + (int) victim.getStat().getLuk());
c.getPlayer().dropMessage(5, "物理攻击: " + victim.getStat().getTotalWatk() + " || 魔法攻击: " + victim.getStat().getTotalMagic());
c.getPlayer().dropMessage(5, "经验倍率: " + victim.getStat().expBuff + " 金币倍率: " + victim.getStat().mesoBuff + " 掉宝倍率: " + victim.getStat().dropBuff);
c.getPlayer().dropMessage(5, "点券: " + victim.getOfflineAcash(victim) + " 抵用: " + victim.getCSPoints(2) + " 金币: " + victim.getMeso() + " 仓库金币 " + mesoInStorage);
c.getPlayer().dropMessage(5, "赞助红利: " + victim.getCSPoints(3));
c.getPlayer().dropMessage(5, "赞助总额: " + victim.getMoneyAll() + " 新台币");
if (ch <= 0) {
c.getPlayer().dropMessage(5, "该角色为离线状态");
} else {
c.getPlayer().dropMessage(5, "IP:" + victim.getClient().getSessionIPAddress() + " 目前MAC:" + victim.getNowMacs() + " 所有MAC:" + victim.getClient().getMacs());
c.getPlayer().dropMessage(5, "对服务器延迟: " + victim.getClient().getLatency());
}
}
} else {
c.getPlayer().dropMessage(5, "找不到此玩家.");
}
return true;
}
@Override
public String getMessage() {
return "!" + this.getClass().getSimpleName().toLowerCase() + " <玩家名字> - 观察玩家";
}
}
public static class spyid extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
if (splitted.length < 2) {
return false;
}
final int id = Integer.parseInt(splitted[1]);
final MapleCharacter victim = MapleCharacter.getCharacterById(id);
final int ch = Find.findChannel(id);
if (victim != null) {
if (victim.getGMLevel() > c.getPlayer().getGMLevel()) {
c.getPlayer().dropMessage(5, "你不能查看比你高权限的人!");
} else {
int mesoInStorage = 0;
try {
if (victim.getStorage() != null) {
mesoInStorage = victim.getStorage().getMeso();
}
} catch (Exception ex) {
}
c.getPlayer().dropMessage(5, "此玩家状态:");
c.getPlayer().dropMessage(5, "玩家名称: " + victim.getName() + " 玩家编号: " + victim.getId() + " 账号: " + victim.getClient().getAccountName() + " 账号ID: " + victim.getAccountID());
c.getPlayer().dropMessage(5, "玩家权限: " + victim.getGMLevel() + " 等级: " + (int) victim.getLevel() + " 职业: " + (int) victim.getJob() + " 名声: " + (int) victim.getFame());
c.getPlayer().dropMessage(5, "地图: " + victim.getMapId() + " - " + victim.getMap().getMapName());
c.getPlayer().dropMessage(5, "目前HP: " + (int) victim.getStat().getHp() + " 目前MP: " + (int) victim.getStat().getMp());
c.getPlayer().dropMessage(5, "最大HP: " + (int) victim.getStat().getMaxHp() + " 最大MP: " + (int) victim.getStat().getMaxMp());
c.getPlayer().dropMessage(5, "力量: " + (int) victim.getStat().getStr() + " || 敏捷: " + (int) victim.getStat().getDex() + " || 智力: " + (int) victim.getStat().getInt() + " || 幸运: " + (int) victim.getStat().getLuk());
c.getPlayer().dropMessage(5, "物理攻击: " + victim.getStat().getTotalWatk() + " || 魔法攻击: " + victim.getStat().getTotalMagic());
c.getPlayer().dropMessage(5, "经验倍率: " + victim.getStat().expBuff + " 金币倍率: " + victim.getStat().mesoBuff + " 掉宝倍率: " + victim.getStat().dropBuff);
c.getPlayer().dropMessage(5, "点券: " + victim.getOfflineAcash(victim) + " 抵用: " + victim.getCSPoints(2) + " 金币: " + victim.getMeso() + " 仓库金币 " + mesoInStorage);
c.getPlayer().dropMessage(5, "赞助红利: " + victim.getCSPoints(3));
c.getPlayer().dropMessage(5, "赞助总额: " + victim.getMoneyAll() + " 新台币");
if (ch <= 0) {
c.getPlayer().dropMessage(5, "该角色为离线状态");
} else {
c.getPlayer().dropMessage(5, "IP:" + victim.getClient().getSessionIPAddress() + " 目前MAC:" + victim.getNowMacs() + " 所有MAC:" + victim.getClient().getMacs());
c.getPlayer().dropMessage(5, "对服务器延迟: " + victim.getClient().getLatency());
}
}
} else {
c.getPlayer().dropMessage(5, "找不到此玩家.");
}
return true;
}
@Override
public String getMessage() {
return "!" + this.getClass().getSimpleName().toLowerCase() + " <玩家ID> - 观察玩家";
}
}
public static class Map extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
if (splitted.length < 2) {
return false;
}
try {
final MapleMap target = c.getChannelServer().getMapFactory().getMap(Integer.parseInt(splitted[1]));
if (target == null) {
c.getPlayer().dropMessage(5, "地图不存在.");
return true;
}
MaplePortal targetPortal = null;
if (splitted.length > 2) {
try {
targetPortal = target.getPortal(Integer.parseInt(splitted[2]));
} catch (IndexOutOfBoundsException e2) {
c.getPlayer().dropMessage(5, "传送点错误.");
} catch (NumberFormatException ex) {
}
}
if (targetPortal == null) {
targetPortal = target.getPortal(0);
}
c.getPlayer().changeMap(target, targetPortal);
} catch (Exception e) {
c.getPlayer().dropMessage(5, "Error: " + e.getMessage());
}
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!map <mapid|charname> [portal] - 传送到某地图/人").toString();
}
}
public static class WarpMap extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
try {
final MapleMap target = c.getChannelServer().getMapFactory().getMap(Integer.parseInt(splitted[1]));
if (target == null) {
c.getPlayer().dropMessage(6, "地图不存在。");
return false;
}
final MapleMap from = c.getPlayer().getMap();
for (final MapleCharacter chr : from.getCharactersThreadsafe()) {
chr.changeMap(target, target.getPortal(0));
}
} catch (Exception e) {
return false;
}
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!WarpMap \t地图代码\u0010 - 把地图上的人全部传到那张地图").toString();
}
}
public static class Debug extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
c.getPlayer().setDebugMessage(!c.getPlayer().getDebugMessage());
c.getPlayer().dropMessage("DeBug讯息已经" + (c.getPlayer().getDebugMessage() ? "开启" : "关闭"));
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!Debug - 开启Debug讯息").toString();
}
}
public static class CharInfo extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
if (splitted.length < 2) {
return false;
}
final StringBuilder builder = new StringBuilder();
final String name = splitted[1];
final int ch = Find.findChannel(name);
if (ch <= 0) {
c.getPlayer().dropMessage(6, "玩家必须上线");
return true;
}
final MapleCharacter other = ChannelServer.getInstance(ch).getPlayerStorage().getCharacterByName(name);
if (other == null) {
builder.append("角色不存在");
c.getPlayer().dropMessage(6, builder.toString());
} else {
if (other.getClient().getLastPing() <= 0L) {
other.getClient().sendPing();
}
builder.append(MapleClient.getLogMessage(other, ""));
builder.append("").append(other.getPosition().x);
builder.append(" /").append(other.getPosition().y);
builder.append(" || 血量 : ");
builder.append((int) other.getStat().getHp());
builder.append(" /");
builder.append((int) other.getStat().getCurrentMaxHp());
builder.append(" || 魔量 : ");
builder.append((int) other.getStat().getMp());
builder.append(" /");
builder.append((int) other.getStat().getCurrentMaxMp());
builder.append(" || 物理攻击力 : ");
builder.append(other.getStat().getTotalWatk());
builder.append(" || 魔法攻击力 : ");
builder.append(other.getStat().getTotalMagic());
builder.append(" || 最高攻击 : ");
builder.append(other.getStat().getCurrentMaxBaseDamage());
builder.append(" || 攻击%数 : ");
builder.append(other.getStat().dam_r);
builder.append(" || BOSS攻击%数 : ");
builder.append(other.getStat().bossdam_r);
builder.append(" || 力量 : ");
builder.append((int) other.getStat().getStr());
builder.append(" || 敏捷 : ");
builder.append((int) other.getStat().getDex());
builder.append(" || 智力 : ");
builder.append((int) other.getStat().getInt());
builder.append(" || 幸运 : ");
builder.append((int) other.getStat().getLuk());
builder.append(" || 全部力量 : ");
builder.append(other.getStat().getTotalStr());
builder.append(" || 全部敏捷 : ");
builder.append(other.getStat().getTotalDex());
builder.append(" || 全部智力 : ");
builder.append(other.getStat().getTotalInt());
builder.append(" || 全部幸运 : ");
builder.append(other.getStat().getTotalLuk());
builder.append(" || 经验值 : ");
builder.append(other.getExp());
builder.append(" || 组队状态 : ");
builder.append(other.getParty() != null);
builder.append(" || 交易状态: ");
builder.append(other.getTrade() != null);
builder.append(" || Latency: ");
builder.append(other.getClient().getLatency());
builder.append(" || 最后PING: ");
builder.append(other.getClient().getLastPing());
builder.append(" || 最后PONG: ");
builder.append(other.getClient().getLastPong());
builder.append(" || IP: ");
builder.append(other.getClient().getSessionIPAddress());
other.getClient().DebugMessage(builder);
c.getPlayer().dropMessage(6, builder.toString());
}
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!charinfo <角色名称> - 查看角色状态").toString();
}
}
public static class Cheaters extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
final List<CheaterData> cheaters = World.getCheaters();
for (int x = cheaters.size() - 1; x >= 0; --x) {
final CheaterData cheater = (CheaterData) cheaters.get(x);
c.getPlayer().dropMessage(6, cheater.getInfo());
}
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!cheaters - 查看作弊角色").toString();
}
}
public static class ItemCheck extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
if (splitted.length < 3 || splitted[1] == null || splitted[1].equals("") || splitted[2] == null || splitted[2].equals("")) {
return false;
}
final int item = Integer.parseInt(splitted[2]);
final String name = splitted[1];
final int ch = Find.findChannel(name);
if (ch <= 0) {
c.getPlayer().dropMessage(6, "玩家必须上线");
return true;
}
final MapleCharacter chr = ChannelServer.getInstance(ch).getPlayerStorage().getCharacterByName(name);
final int itemamount = chr.getItemQuantity(item, true);
if (itemamount > 0) {
c.getPlayer().dropMessage(6, chr.getName() + "" + itemamount + " (" + item + ").");
} else {
c.getPlayer().dropMessage(6, chr.getName() + " 并沒有 (" + item + ")");
}
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!itemcheck <playername> <itemid> - 检查物品").toString();
}
}
public static class CheckGash extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
if (splitted.length < 2) {
return false;
}
final String name = splitted[1];
final int ch = Find.findChannel(name);
if (ch <= 0) {
c.getPlayer().dropMessage(6, "玩家必须上线");
return true;
}
final MapleCharacter chrs = ChannelServer.getInstance(ch).getPlayerStorage().getCharacterByName(name);
if (chrs == null) {
c.getPlayer().dropMessage(5, "找不到该角色");
} else {
c.getPlayer().dropMessage(6, chrs.getName() + "" + chrs.getCSPoints(1) + " 点数.");
}
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!checkgash <玩家名称> - 检查点数").toString();
}
}
public static class whoishere extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
StringBuilder builder = new StringBuilder("在此地图的玩家: ");
for (final MapleCharacter chr : c.getPlayer().getMap().getCharactersThreadsafe()) {
if (builder.length() > 150) {
builder.setLength(builder.length() - 2);
c.getPlayer().dropMessage(6, builder.toString());
builder = new StringBuilder();
}
builder.append(MapleCharacterUtil.makeMapleReadable(chr.getName()));
builder.append(", ");
}
builder.setLength(builder.length() - 2);
c.getPlayer().dropMessage(6, builder.toString());
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!whoishere - 查看目前地图上的玩家").toString();
}
}
public static class Connected extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
final java.util.Map<Integer, Integer> connected = World.getConnected();
final StringBuilder conStr = new StringBuilder("已连接的客戶端: ");
boolean first = true;
final Iterator<Integer> iterator = connected.keySet().iterator();
while (iterator.hasNext()) {
final int i = ((Integer) iterator.next()).intValue();
if (!first) {
conStr.append(", ");
} else {
first = false;
}
if (i == 0) {
conStr.append("所有: ");
conStr.append(connected.get(Integer.valueOf(i)));
} else {
conStr.append("频道 ");
conStr.append(i);
conStr.append(": ");
conStr.append(connected.get(Integer.valueOf(i)));
}
}
c.getPlayer().dropMessage(6, conStr.toString());
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!connected - 查看已连线的客戶端").toString();
}
}
public static class openmap extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
int mapid = 0;
String input = null;
final MapleMap map = null;
if (splitted.length < 2) {
return false;
}
try {
input = splitted[1];
mapid = Integer.parseInt(input);
} catch (Exception ex) {
}
for (final ChannelServer cserv : ChannelServer.getAllInstances()) {
cserv.getMapFactory().HealMap(mapid);
}
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!openmap - 开放地图").toString();
}
}
public static class closemap extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
int mapid = 0;
String input = null;
final MapleMap map = null;
if (splitted.length < 2) {
return false;
}
try {
input = splitted[1];
mapid = Integer.parseInt(input);
} catch (Exception ex) {
}
if (c.getChannelServer().getMapFactory().getMap(mapid) == null) {
c.getPlayer().dropMessage("地图不存在");
return true;
}
for (final ChannelServer cserv : ChannelServer.getAllInstances()) {
cserv.getMapFactory().destroyMap(mapid, true);
}
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!closemap - 关闭地图").toString();
}
}
public static class 查看玩家状态 extends PlayerStats {
}
public static class PlayerStats extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
if (splitted.length < 2) {
return false;
}
final String name = splitted[1];
final MapleCharacter victim = MapleCharacter.getCharacterByName(name);
final int ch = Find.findChannel(name);
if (victim != null) {
if (victim.getGMLevel() > c.getPlayer().getGMLevel()) {
c.getPlayer().dropMessage(5, "你不能查看比你高权限的人!");
} else if (ch <= 0) {
c.getPlayer().dropMessage(5, "该角色为离线状态");
} else {
c.getPlayer().dropMessage(5, "玩家名称: " + victim.getName() + " 等级: " + (int) victim.getLevel() + " 职业: " + (int) victim.getJob());
c.getPlayer().dropMessage(5, "力量: " + victim.getStr() + " 敏捷: " + victim.getDex() + " 智力: " + victim.getInt() + " 幸运: " + victim.getLuk());
c.getPlayer().dropMessage(5, "HP: " + victim.getHp() + " 最大HP: " + victim.getMaxHp() + " MP: " + victim.getMp() + " 最大MP: " + victim.getMaxMp());
c.getPlayer().dropMessage(5, "Buff技能数量: " + victim.getSkillID().size());
c.getPlayer().dropMessage(5, "技能ID: " + victim.getSkillID().keySet().toString());
}
} else {
c.getPlayer().dropMessage(5, "找不到此玩家.");
}
return true;
}
@Override
public String getMessage() {
return "!" + this.getClass().getSimpleName().toLowerCase() + " <玩家名字> - 查看玩家技能数据";
}
}
public static class 生死活动 extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
final MapleCharacter chr = c.getPlayer();
if (splitted.length < 2) {
c.getPlayer().dropMessage(5, "[用法] !生死活动 <1幹死右边2幹死左边>");
return false;
}
if (chr.getMapId() != 109020001) {
c.getPlayer().dropMessage(5, "只有地图ID为109020001的地图才能使用。");
return true;
}
final int answer = Integer.parseInt(splitted[1]);
final List<MapleCharacter> chrlist = chr.getMap().getCharacters();
for (final MapleCharacter chra : chrlist) {
if (isCorrectAnswer(chra, answer)) {
chra.getStat().setHp(0);
chra.getStat().setMp(0);
chra.updateSingleStat(MapleStat.HP, 0);
chra.updateSingleStat(MapleStat.MP, 0);
}
}
return true;
}
public static boolean isCorrectAnswer(final MapleCharacter chr, final int answer) {
final double x = chr.getTruePosition().getX();
final double y = chr.getTruePosition().getY();
return (x > -234.0 && y > -26.0 && answer == 1) || (x < -234.0 && y > -26.0 && answer == 2);
}
@Override
public String getMessage() {
return "!" + this.getClass().getSimpleName().toLowerCase() + " <1幹死右边2幹死左边>";
}
}
}

View File

@ -0,0 +1,715 @@
package client.messages.commands;
import scripting.EventManager;
import handling.world.MaplePartyCharacter;
import client.inventory.MapleInventory;
import server.MapleInventoryManipulator;
import client.inventory.MapleInventoryType;
import tools.FileoutputUtil;
import handling.world.World.Broadcast;
import constants.PiPiConfig;
import tools.StringUtil;
import java.util.Iterator;
import server.life.MapleMonster;
import server.maps.MapleMapObject;
import java.util.Arrays;
import server.maps.MapleMapObjectType;
import client.MapleCharacter;
import gui.Start;
import tools.MaplePacketCreator;
import client.MapleStat;
import constants.GameConstants;
import scripting.NPCScriptManager;
import client.MapleClient;
import constants.ServerConstants.PlayerGMRank;
public class PlayerCommand {
public static PlayerGMRank getPlayerLevelRequired() {
return PlayerGMRank.普通玩家;
}
public static class 爆率 extends Mobdrop {
}
public static class 全局爆率 extends Mapdrop {
}
public static class 帮助 extends help {
@Override
public String getMessage() {
return new StringBuilder().append("@帮助 - 帮助").toString();
}
}
public static class help extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
NPCScriptManager.getInstance().start(c, 9010000, "玩家指令查询");
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("@help - 帮助").toString();
}
}
public abstract static class OpenNPCCommand extends CommandExecute {
protected int npc;
private static final int[] npcs = new int[]{9010017, 9000001, 9000058, 9330082, 9209002};
public OpenNPCCommand() {
this.npc = -1;
}
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
if (this.npc != 1 && c.getPlayer().getMapId() != 910000000) {
for (final int i : GameConstants.blockedMaps) {
if (c.getPlayer().getMapId() == i) {
c.getPlayer().dropMessage(1, "你不能在这里使用指令.");
return true;
}
}
if (this.npc != 2 && c.getPlayer().getLevel() < 10) {
c.getPlayer().dropMessage(1, "你的等级必须是10等.");
return true;
}
if (c.getPlayer().getMap().getSquadByMap() != null || c.getPlayer().getEventInstance() != null || c.getPlayer().getMap().getEMByMap() != null || c.getPlayer().getMapId() >= 990000000) {
c.getPlayer().dropMessage(1, "你不能在这里使用指令.");
return true;
}
if ((c.getPlayer().getMapId() >= 680000210 && c.getPlayer().getMapId() <= 680000502) || (c.getPlayer().getMapId() / 1000 == 980000 && c.getPlayer().getMapId() != 980000000) || c.getPlayer().getMapId() / 100 == 1030008 || c.getPlayer().getMapId() / 100 == 922010 || c.getPlayer().getMapId() / 10 == 13003000) {
c.getPlayer().dropMessage(1, "你不能在这里使用指令.");
return true;
}
}
NPCScriptManager.getInstance().start(c, OpenNPCCommand.npcs[this.npc]);
return true;
}
}
public static class 丟装 extends DropCash {
@Override
public String getMessage() {
return new StringBuilder().append("@丟装 - 呼叫清除现金道具npc").toString();
}
}
public static class DropCash extends OpenNPCCommand {
public DropCash() {
this.npc = 0;
}
@Override
public String getMessage() {
return new StringBuilder().append("@dropbash - 呼叫清除现金道具npc").toString();
}
}
public static class event extends OpenNPCCommand {
public event() {
this.npc = 1;
}
@Override
public String getMessage() {
return new StringBuilder().append("@event - 呼叫活动npc").toString();
}
}
public static class expfix extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
c.getPlayer().setExp(0);
c.getPlayer().updateSingleStat(MapleStat.EXP, c.getPlayer().getExp());
c.getPlayer().dropMessage(5, "经验修复完成");
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("@expfix - 经验归零").toString();
}
}
public static class TSmega extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
c.getPlayer().setSmega();
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("@TSmega - 开/关闭广播").toString();
}
}
public static class Gashponmega extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
c.getPlayer().setGashponmega();
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("@Gashponmega - 开/关闭转蛋广播").toString();
}
}
public static class 解卡 extends ea {
@Override
public String getMessage() {
return new StringBuilder().append("@解卡 - 解卡").toString();
}
}
public static class 查看 extends ea {
@Override
public String getMessage() {
return new StringBuilder().append("@查看 - 解卡").toString();
}
}
public static class ea extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
c.removeClickedNPC();
NPCScriptManager.getInstance().dispose(c);
c.getSession().write(MaplePacketCreator.enableActions());
c.getPlayer().dropMessage(1, "刷新人物完毕.");
c.getPlayer().dropMessage(6, "当前延迟 " + c.getPlayer().getClient().getLatency() + " 毫秒");
if (c.getPlayer().isAdmin()) {
c.getPlayer().getMap().broadcastMessage(MaplePacketCreator.boatEffect(1034));
}
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("@ea - 解卡").toString();
}
}
public static class 怪物 extends mob {
@Override
public String getMessage() {
return new StringBuilder().append("@怪物 - 查看怪物状态").toString();
}
}
public static class 刷钱模式 extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
if (c.getPlayer().getBossLog("刷钱模式介绍") == 0) {
c.getPlayer().dropMessage(6, "刷钱模式总共2种模式通过 @刷钱模式 进行切换");
c.getPlayer().dropMessage(6, "1.全部材料和装备都会自动帮你售卖为金币 2.只会自动帮你售卖掉落的装备、子弹、标");
c.getPlayer().setBossLog("刷钱模式介绍");
}
if (c.getPlayer().getItemQuantity(((Integer) Start.ConfigValuesMap.get("自动刷钱道具")).intValue(), true) < 1) {
return false;
}
final MapleCharacter player = c.getPlayer();
if (player.get刷钱模式() == 0) {
player.set刷钱模式(1);
player.dropMessage(6, "刷钱模式已经开启 - 全部材料和装备都会自动帮你售卖为金币");
} else if (player.get刷钱模式() == 1) {
player.set刷钱模式(2);
player.dropMessage(6, "刷钱模式已经开启 - 只会自动帮你售卖掉落的装备、子弹、标");
} else {
player.set刷钱模式(0);
player.dropMessage(6, "刷钱模式已经关闭.");
}
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("@刷钱模式 - 开启自动出售道具").toString();
}
}
public static class mob extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
MapleMonster monster = null;
for (final MapleMapObject monstermo : c.getPlayer().getMap().getMapObjectsInRange(c.getPlayer().getPosition(), 100000.0, Arrays.asList(MapleMapObjectType.MONSTER))) {
monster = (MapleMonster) monstermo;
if (monster.isAlive()) {
if (monster.getStats().isBoss() && !c.getPlayer().isGM() && ((Integer) Start.ConfigValuesMap.get("怪物血量显示开关")).intValue() < 1) {
c.getPlayer().dropMessage(6, "[领主怪物]:由于强大的力量,领主的血量被保护了起来 ");
} else {
c.getPlayer().dropMessage(6, "怪物 " + monster.toString());
}
}
}
if (monster == null) {
c.getPlayer().dropMessage(6, "找不到地图上的怪物");
}
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("@mob - 查看怪物状态").toString();
}
}
public static class CGM extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
boolean autoReply = false;
if (splitted.length < 2) {
return false;
}
final String talk = StringUtil.joinStringFrom(splitted, 1);
if (c.getPlayer().isGM()) {
c.getPlayer().dropMessage(6, "因为你自己是GM所以无法使用此指令,可以尝试!cngm <讯息> 来建立GM聊天频道~");
} else if (!c.getPlayer().getCheatTracker().GMSpam(100000, 1)) {
boolean fake = false;
boolean showmsg = true;
if (PiPiConfig.getBlackList().containsKey(Integer.valueOf(c.getAccID()))) {
fake = true;
}
if (talk.contains((CharSequence) "") && talk.contains((CharSequence) "")) {
c.getPlayer().dropMessage(1, "抢图自行解決!!");
fake = true;
showmsg = false;
} else if ((talk.contains((CharSequence) "") && talk.contains((CharSequence) "")) || (talk.contains((CharSequence) "") && talk.contains((CharSequence) ""))) {
c.getPlayer().dropMessage(1, "被骗请自行解決");
fake = true;
showmsg = false;
} else if (talk.contains((CharSequence) "") && (talk.contains((CharSequence) "") || talk.contains((CharSequence) "")) && talk.contains((CharSequence) "")) {
c.getPlayer().dropMessage(1, "刪错角色请自行解決");
fake = true;
showmsg = false;
} else if (talk.contains((CharSequence) "") && talk.contains((CharSequence) "") && talk.contains((CharSequence) "")) {
c.getPlayer().dropMessage(1, "请自行解決");
fake = true;
showmsg = false;
}
if (talk.toUpperCase().contains((CharSequence) "VIP") && (talk.contains((CharSequence) "") || talk.contains((CharSequence) "")) && talk.contains((CharSequence) "")) {
c.getPlayer().dropMessage(1, "VIP将会于储值后一段时间后自行发放请耐心等待");
autoReply = true;
} else if (talk.contains((CharSequence) "贡献") || talk.contains((CharSequence) "666") || ((talk.contains((CharSequence) "") || talk.contains((CharSequence) "") || talk.contains((CharSequence) "") || talk.contains((CharSequence) "")) && (talk.contains((CharSequence) "") || talk.contains((CharSequence) "") || talk.contains((CharSequence) "")) && talk.contains((CharSequence) ""))) {
c.getPlayer().dropMessage(1, "勋章请去点拍卖NPC案领取勋章\r\n如尚未被加入清单请耐心等候GM。");
autoReply = true;
} else if ((talk.contains((CharSequence) "商人") && talk.contains((CharSequence) "")) || (talk.contains((CharSequence) "商店") && talk.contains((CharSequence) "补偿"))) {
c.getPlayer().dropMessage(1, "目前精灵商人装备和金币有机率被吃\r\n如被吃了请务必将当时的情況完整描述给管理员\r\n\r\nPS: 不会补偿任何物品");
autoReply = true;
} else if (talk.contains((CharSequence) "") && talk.contains((CharSequence) "") && talk.contains((CharSequence) "") && talk.contains((CharSequence) "")) {
c.getPlayer().dropMessage(1, "档案受损请重新解压縮主程式写");
autoReply = true;
} else if ((talk.contains((CharSequence) "") || talk.contains((CharSequence) "")) && ((talk.contains((CharSequence) "") && talk.contains((CharSequence) "") && talk.contains((CharSequence) "")) || talk.toUpperCase().contains((CharSequence) "SP"))) {
c.getPlayer().dropMessage(1, "缺少技能点请重练,沒有其他方法了写");
autoReply = true;
}
if (showmsg) {
c.getPlayer().dropMessage(6, "讯息已经寄送给GM了!");
}
if (!fake) {
Broadcast.broadcastGMMessage(MaplePacketCreator.serverNotice(6, "[管理员帮帮忙]频道 " + c.getPlayer().getClient().getChannel() + " 玩家 [" + c.getPlayer().getName() + "] (" + c.getPlayer().getId() + "): " + talk + (autoReply ? " -- (系统已自动回复)" : "")));
}
FileoutputUtil.logToFile("logs/data/管理员帮帮忙.txt", "\r\n " + FileoutputUtil.NowTime() + " 玩家[" + c.getPlayer().getName() + "] 账号[" + c.getAccountName() + "]: " + talk + (autoReply ? " -- (系统已自动回复)" : "") + "\r\n");
} else {
c.getPlayer().dropMessage(6, "为了防止对GM刷屏所以每1分钟只能发一次.");
}
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("@cgm - 跟GM回报").toString();
}
}
public static class 清除道具 extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
if (splitted.length < 4) {
return false;
}
String Column = "null";
int start = -1;
int end = -1;
try {
Column = splitted[1];
start = Integer.parseInt(splitted[2]);
end = Integer.parseInt(splitted[3]);
} catch (Exception ex) {
}
if (start == -1 || end == -1) {
c.getPlayer().dropMessage("@清除道具 <装备栏/消耗栏/装饰栏/其他栏/特殊栏> <开始格数> <结束格数>");
return true;
}
if (start < 1) {
start = 1;
}
if (end > 96) {
end = 96;
}
final String s = Column;
MapleInventoryType type = null;
switch (s) {
case "装备栏": {
type = MapleInventoryType.EQUIP;
break;
}
case "消耗栏": {
type = MapleInventoryType.USE;
break;
}
case "装饰栏": {
type = MapleInventoryType.SETUP;
break;
}
case "其他栏": {
type = MapleInventoryType.ETC;
break;
}
case "特殊栏": {
type = MapleInventoryType.CASH;
break;
}
default: {
type = null;
break;
}
}
if (type == null) {
c.getPlayer().dropMessage("@清除道具 <装备栏/消耗栏/装饰栏/其他栏/特殊栏> <开始格数> <结束格数>");
return true;
}
final MapleInventory inv = c.getPlayer().getInventory(type);
for (int i = start; i <= end; ++i) {
if (inv.getItem((short) i) != null) {
MapleInventoryManipulator.removeFromSlot(c, type, (short) i, inv.getItem((short) i).getQuantity(), true);
}
}
FileoutputUtil.logToFile("logs/Data/玩家指令.txt", "\r\n " + FileoutputUtil.NowTime() + " IP: " + c.getSession().remoteAddress().toString().split(":")[0] + " 账号: " + c.getAccountName() + " 玩家: " + c.getPlayer().getName() + " 使用了指令 " + StringUtil.joinStringFrom(splitted, 0));
c.getPlayer().dropMessage(6, "您已经清除了第 " + start + " 格到 " + end + "格的" + Column + "道具");
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("@清除道具 <装备栏/消耗栏/装饰栏/其他栏/特殊栏> <开始格数> <结束格数>").toString();
}
}
public static class jk_hm extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
c.getPlayer().RemoveHired();
c.getPlayer().dropMessage("卡精灵商人已经解除");
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("@jk_hm - 卡精灵商人解除").toString();
}
}
public static class jcds extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
int gain = c.getPlayer().getMP();
if (gain <= 0) {
c.getPlayer().dropMessage("目前沒有任何在线点数写。");
return true;
}
if (splitted.length < 2) {
c.getPlayer().dropMessage("目前抵用: " + c.getPlayer().getCSPoints(2));
c.getPlayer().dropMessage("目前在线点数已经累积: " + gain + " 点,若要领取请输入 @jcds true");
} else if ("true".equals(splitted[1])) {
gain = c.getPlayer().getMP();
c.getPlayer().modifyCSPoints(2, gain, true);
c.getPlayer().setMP(0);
c.getPlayer().saveToDB(false, false);
c.getPlayer().dropMessage("领取了 " + gain + " 点在线点数, 目前抵用: " + c.getPlayer().getCSPoints(2));
}
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("@jcds - 领取在线点数").toString();
}
}
public static class 在线点数 extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
int gain = c.getPlayer().getMP();
if (gain <= 0) {
c.getPlayer().dropMessage("目前沒有任何在线点数写。");
return true;
}
if (splitted.length < 2) {
c.getPlayer().dropMessage("目前抵用: " + c.getPlayer().getCSPoints(2));
c.getPlayer().dropMessage("目前在线点数已经累积: " + gain + " 点,若要领取请输入 @在线点数 是");
} else if ("".equals(splitted[1])) {
gain = c.getPlayer().getMP();
c.getPlayer().modifyCSPoints(2, gain, true);
c.getPlayer().setMP(0);
c.getPlayer().saveToDB(false, false);
c.getPlayer().dropMessage("领取了 " + gain + " 点在线点数, 目前抵用: " + c.getPlayer().getCSPoints(2));
}
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("@在线点数 - 领取在线点数").toString();
}
}
public static class 丟弃点装 extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
c.sendPacket(MaplePacketCreator.enableActions());
NPCScriptManager.getInstance().start(c, 9010000, "丟弃点装");
return true;
}
@Override
public String getMessage() {
return "@" + this.getClass().getSimpleName().toLowerCase() + "丟弃点装 [点装在装备栏的位置]";
}
}
public static class Mobdrop extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
NPCScriptManager.getInstance().start(c, 9900006);
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("@Mobdrop").toString();
}
}
public static class Mapdrop extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
NPCScriptManager.getInstance().start(c, 9900006, "全局爆率");
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("@Mapdrop").toString();
}
}
public abstract static class DistributeStatCommands extends CommandExecute {
protected MapleStat stat;
public DistributeStatCommands() {
this.stat = null;
}
private void setStat(final MapleCharacter player, final int amount) {
switch (this.stat) {
case STR: {
player.getStat().setStr((short) amount);
player.updateSingleStat(MapleStat.STR, (int) player.getStat().getStr());
break;
}
case DEX: {
player.getStat().setDex((short) amount);
player.updateSingleStat(MapleStat.DEX, (int) player.getStat().getDex());
break;
}
case INT: {
player.getStat().setInt((short) amount);
player.updateSingleStat(MapleStat.INT, (int) player.getStat().getInt());
break;
}
case LUK: {
player.getStat().setLuk((short) amount);
player.updateSingleStat(MapleStat.LUK, (int) player.getStat().getLuk());
break;
}
}
}
private int getStat(final MapleCharacter player) {
switch (this.stat) {
case STR: {
return player.getStat().getStr();
}
case DEX: {
return player.getStat().getDex();
}
case INT: {
return player.getStat().getInt();
}
case LUK: {
return player.getStat().getLuk();
}
default: {
throw new RuntimeException();
}
}
}
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
if (splitted.length < 2) {
c.getPlayer().dropMessage(5, "输入的数字无效.");
return false;
}
int change = 0;
try {
change = Integer.parseInt(splitted[1]);
} catch (NumberFormatException nfe) {
c.getPlayer().dropMessage(5, "输入的数字无效.");
return false;
}
if (change <= 0) {
c.getPlayer().dropMessage(5, "您必须输入一个大于 0 的数字.");
return false;
}
if (c.getPlayer().getRemainingAp() < change) {
c.getPlayer().dropMessage(5, "您的能力点不足.");
return false;
}
final int number = this.getStat(c.getPlayer()) + change;
if (number >= 32767) {
return false;
}
this.setStat(c.getPlayer(), this.getStat(c.getPlayer()) + change);
c.getPlayer().setRemainingAp((short) (c.getPlayer().getRemainingAp() - change));
c.getPlayer().updateSingleStat(MapleStat.AVAILABLEAP, (int) c.getPlayer().getRemainingAp());
c.getPlayer().dropMessage(5, "加点成功您的 " + StringUtil.makeEnumHumanReadable(this.stat.name()) + " 提高了 " + change + " 点.");
return true;
}
}
public static class 力量 extends DistributeStatCommands {
public 力量() {
this.stat = MapleStat.STR;
}
@Override
public String getMessage() {
return new StringBuilder().append("@力量 - 力量").toString();
}
}
public static class 敏捷 extends DistributeStatCommands {
public 敏捷() {
this.stat = MapleStat.DEX;
}
@Override
public String getMessage() {
return new StringBuilder().append("@敏捷 - 敏捷").toString();
}
}
public static class 智力 extends DistributeStatCommands {
public 智力() {
this.stat = MapleStat.INT;
}
@Override
public String getMessage() {
return new StringBuilder().append("@智力 - 智力").toString();
}
}
public static class 运气 extends DistributeStatCommands {
public 运气() {
this.stat = MapleStat.LUK;
}
@Override
public String getMessage() {
return new StringBuilder().append("@运气 - 运气").toString();
}
}
public static class jkzd extends 解卡组队 {
}
public static class 解卡组队 extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
c.getPlayer().setParty(null);
c.getPlayer().dropMessage(1, "解卡组队成功,赶紧去组队把。");
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("@解卡组队-游戏无法进行组队的时候输入").toString();
}
}
public static class 副本拉人 extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
if (c.getPlayer().getEventInstance() != null) {
if (c.getChannelServer().getEventSMA().getEventManager(c.getPlayer().getEventInstance().getName()) != null) {
final EventManager em = c.getChannelServer().getEventSMA().getEventManager(c.getPlayer().getEventInstance().getName());
} else if (c.getChannelServer().getEventSMB().getEventManager(c.getPlayer().getEventInstance().getName()) != null) {
c.getChannelServer().getEventSMB().getEventManager(c.getPlayer().getEventInstance().getName());
}
EventManager em;
if (c.getChannelServer().getEventSMC().getEventManager(c.getPlayer().getEventInstance().getName()) != null) {
em = c.getChannelServer().getEventSMC().getEventManager(c.getPlayer().getEventInstance().getName());
} else {
if (c.getChannelServer().getEventSM().getEventManager(c.getPlayer().getEventInstance().getName()) == null) {
c.getPlayer().dropMessage(1, "你这是什么鬼副本找都没找到");
return false;
}
em = c.getChannelServer().getEventSM().getEventManager(c.getPlayer().getEventInstance().getName());
}
final EventManager eim = em;
for (final MaplePartyCharacter chr : c.getPlayer().getParty().getMembers()) {
final MapleCharacter curChar = c.getChannelServer().getPlayerStorage().getCharacterById(chr.getId());
if (eim.getProperty("joinid").indexOf("" + curChar.getId()) == -1) {
c.getPlayer().dropMessage(1, "偷鸡么,你想拉谁搞事情啊把偷鸡的人给我t了!");
return false;
}
final int Map = c.getPlayer().getMapId();
if (curChar.getMapId() == Map) {
continue;
}
curChar.dropMessage(1, "你的队友拉你回副本,稍后就会传送至队友身边。");
new Thread() {
@Override
public void run() {
try {
Thread.sleep(3000L);
if (curChar != null) {
eim.startInstancea(curChar);
}
} catch (InterruptedException ex) {
}
}
}.start();
}
return true;
}
c.getPlayer().dropMessage(1, "我拉你个pp虾,都不在副本拉拉,去厕所把!!");
return false;
}
@Override
public String getMessage() {
return new StringBuilder().append("@副本拉人-副本或者boss击杀过程中有人掉线可以拉回").toString();
}
}
}

View File

@ -0,0 +1,286 @@
package client.messages.commands;
import java.util.Iterator;
import java.sql.PreparedStatement;
import java.sql.Connection;
import java.sql.SQLException;
import client.LoginCrypto;
import database.DBConPool;
import handling.login.handler.AutoRegister;
import server.maps.MapleMap;
import client.MapleCharacter;
import handling.world.World.Broadcast;
import tools.MaplePacketCreator;
import tools.FileoutputUtil;
import handling.channel.ChannelServer;
import handling.world.World.Find;
import tools.StringUtil;
import client.MapleClient;
import constants.ServerConstants.PlayerGMRank;
public class PracticerCommand {
public static PlayerGMRank getPlayerLevelRequired() {
return PlayerGMRank.新实习生;
}
public static class Ban extends CommandExecute {
protected boolean hellban;
public Ban() {
this.hellban = false;
}
private String getCommand() {
return "Ban";
}
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
if (splitted.length < 2) {
return false;
}
final StringBuilder sb = new StringBuilder(c.getPlayer().getName());
sb.append(" 封锁 ").append(splitted[1]).append(": ").append(StringUtil.joinStringFrom(splitted, 2));
boolean offline = false;
boolean ban = false;
String name = "";
String input = "null";
try {
name = splitted[1];
input = splitted[2];
} catch (Exception ex) {
}
final int ch = Find.findChannel(name);
if (ch <= 0) {
if (!c.getPlayer().OfflineBanByName(name, sb.toString())) {
c.getPlayer().dropMessage(6, "[" + this.getCommand() + "] 封锁失败 " + splitted[1]);
return true;
}
c.getPlayer().dropMessage(6, "[" + this.getCommand() + "] 成功离线封锁 " + splitted[1] + ".");
ban = true;
offline = true;
} else {
final MapleCharacter target = ChannelServer.getInstance(ch).getPlayerStorage().getCharacterByName(name);
if (target != null) {
if (c.getPlayer().getGMLevel() < target.getGMLevel()) {
c.getPlayer().dropMessage(6, "[" + this.getCommand() + "] 无法封锁GMs...");
return true;
}
sb.append(" (IP: ").append(target.getClient().getSessionIPAddress()).append(")");
if (!target.ban(sb.toString(), c.getPlayer().hasGmLevel(5), false, this.hellban)) {
c.getPlayer().dropMessage(6, "[" + this.getCommand() + "] 封锁失败.");
return true;
}
ban = true;
c.getPlayer().dropMessage(6, "[" + this.getCommand() + "] 成功封锁 " + target.getName() + ".");
target.getClient().getSession().close();
}
}
FileoutputUtil.logToFile("logs/Hack/指令封锁名单.txt", "\r\n " + FileoutputUtil.NowTime() + " " + c.getPlayer().getName() + " 封锁了 " + splitted[1] + " 原因: " + sb.toString() + " 是否离线封锁: " + offline);
final String reason = "null".equals(input) ? "使用违法程式练功" : StringUtil.joinStringFrom(splitted, 2);
Broadcast.broadcastMessage(MaplePacketCreator.serverNotice(6, "[封锁系统] " + splitted[1] + " 因为" + reason + "而被管理员永久停权。"));
final String msg = "[GM 密语] GM " + c.getPlayer().getName() + " 封锁了 " + splitted[1] + " 是否离线封锁 " + offline + " 原因:" + reason;
Broadcast.broadcastGMMessage(MaplePacketCreator.serverNotice(6, msg));
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!ban <玩家> <原因> - 封锁玩家").toString();
}
}
public static class WarpHere extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
if (splitted.length < 2) {
return false;
}
MapleCharacter victim = c.getChannelServer().getPlayerStorage().getCharacterByName(splitted[1]);
if (victim != null) {
victim.changeMap(c.getPlayer().getMap(), c.getPlayer().getMap().findClosestSpawnpoint(c.getPlayer().getPosition()));
} else {
final int ch = Find.findChannel(splitted[1]);
if (ch < 0) {
c.getPlayer().dropMessage(5, "找不到");
} else {
victim = ChannelServer.getInstance(ch).getPlayerStorage().getCharacterByName(splitted[1]);
c.getPlayer().dropMessage(5, "正在把玩家传到这来");
victim.dropMessage(5, "正在传送到GM那边");
if (victim.getMapId() != c.getPlayer().getMapId()) {
final MapleMap mapp = victim.getClient().getChannelServer().getMapFactory().getMap(c.getPlayer().getMapId());
victim.changeMap(mapp, mapp.getPortal(0));
}
victim.changeChannel(c.getChannel());
}
}
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!warphere 把玩家传送到这里").toString();
}
}
public static class Warp extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
if (splitted.length < 2) {
return false;
}
String input = "";
try {
input = splitted[1];
} catch (Exception ex2) {
}
MapleCharacter victim = c.getChannelServer().getPlayerStorage().getCharacterByName(input);
if (victim != null) {
if (splitted.length == 2) {
c.getPlayer().changeMap(victim.getMap(), victim.getMap().findClosestSpawnpoint(victim.getPosition()));
} else {
MapleMap target = null;
try {
target = ChannelServer.getInstance(c.getChannel()).getMapFactory().getMap(Integer.parseInt(splitted[2]));
} catch (Exception ex3) {
}
if (target == null) {
c.getPlayer().dropMessage(6, "地图不存在");
} else {
victim.changeMap(target, target.getPortal(0));
}
}
} else {
final int ch = Find.findChannel(input);
if (ch < 0) {
Integer map = null;
MapleMap target2 = null;
try {
map = Integer.valueOf(Integer.parseInt(input));
target2 = c.getChannelServer().getMapFactory().getMap(map.intValue());
} catch (Exception ex) {
if (map == null || target2 == null) {
c.getPlayer().dropMessage(6, "地图不存在");
return true;
}
}
if (target2 == null) {
c.getPlayer().dropMessage(6, "地图不存在");
} else {
c.getPlayer().changeMap(target2, target2.getPortal(0));
}
} else {
victim = ChannelServer.getInstance(ch).getPlayerStorage().getCharacterByName(input);
if (victim != null) {
if (victim.getMapId() != c.getPlayer().getMapId()) {
final MapleMap mapp = c.getChannelServer().getMapFactory().getMap(victim.getMapId());
c.getPlayer().changeMap(mapp, mapp.getPortal(0));
}
c.getPlayer().dropMessage(6, "正在改变频道请等待");
c.getPlayer().changeChannel(ch);
} else {
c.getPlayer().dropMessage(6, "角色不存在");
}
}
}
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!warp [玩家名称] <地图ID> - 移动到某个地图或某个玩家所在的地方").toString();
}
}
public static class 注册 extends register {
}
public static class register extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
String acc = null;
String password = null;
try {
acc = splitted[1];
password = splitted[2];
} catch (Exception ex3) {
}
if (acc == null || password == null) {
c.getPlayer().dropMessage("账号或密码异常");
return false;
}
final boolean ACCexist = AutoRegister.getAccountExists(acc);
if (ACCexist) {
c.getPlayer().dropMessage("帐号已被使用");
return false;
}
if (acc.length() >= 12) {
c.getPlayer().dropMessage("密码长度过长");
return false;
}
Connection con;
try {
con = (Connection) DBConPool.getInstance().getDataSource().getConnection();
} catch (Exception ex) {
System.out.println(ex);
return false;
}
try (final PreparedStatement ps = con.prepareStatement("INSERT INTO accounts (name, password) VALUES (?, ?)")) {
ps.setString(1, acc);
ps.setString(2, LoginCrypto.hexSha1(password));
ps.executeUpdate();
ps.close();
} catch (SQLException ex2) {
System.out.println(ex2);
return false;
}
c.getPlayer().dropMessage("[注册完成]账号: " + acc + " 密码: " + password);
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!注册 [账号] <密码> - 注册账号").toString();
}
}
public static class 线上玩家 extends CommandExecute {
@Override
public boolean execute(final MapleClient c, final String[] splitted) {
int total = 0;
c.getPlayer().dropMessage(6, "---------------------------------------------------------------------------------------");
for (final ChannelServer cserv : ChannelServer.getAllInstances()) {
final int curConnected = cserv.getConnectedClients();
c.getPlayer().dropMessage(6, "频道: " + cserv.getChannel() + " 在线人数: " + curConnected);
total += curConnected;
for (final MapleCharacter chr : cserv.getPlayerStorage().getAllCharacters()) {
if (chr != null && c.getPlayer().getGMLevel() >= chr.getGMLevel()) {
final StringBuilder ret = new StringBuilder();
ret.append(StringUtil.getRightPaddedStr(chr.getName(), ' ', 13));
ret.append(" ID: ");
ret.append(chr.getId());
ret.append(" 等级: ");
ret.append(StringUtil.getRightPaddedStr(String.valueOf((int) chr.getLevel()), ' ', 3));
if (chr.getMap() != null) {
ret.append(" 地图: ");
ret.append(chr.getMapId());
ret.append(" - ");
ret.append(chr.getMap().getMapName());
}
c.getPlayer().dropMessage(6, ret.toString());
}
}
}
c.getPlayer().dropMessage(6, "当前服务器总计在线: " + total);
c.getPlayer().dropMessage(6, "---------------------------------------------------------------------------------------");
return true;
}
@Override
public String getMessage() {
return new StringBuilder().append("!线上玩家 - 查看线上玩家").toString();
}
}
}

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More