MXD-Server/src/client/inventory/ItemLoader.java

309 lines
15 KiB
Java
Raw Normal View History

2025-03-03 15:16:22 +08:00
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"));
1 游戏: 给【怪物血量】和【服务端计算伤害】突破long的限制(9223372036854775807)目前最高922京,可以用测试伤害那个脚本测试,脚本里面改怪物血量 (万 、亿 、兆、 京 、垓、秭、穰、沟、涧、正、载、极、恒河沙、阿僧祗、那由他、不可思议、无量、大数、古戈尔、频菠萝、矜羯罗、不可说不可说转、超限数、绝对无限、绝对无量、绝对小数、绝对大数、绝对超限数) 总共28个单位,每个单位是前一个单位的1万倍 同时人物头顶的信息显示也要显示,每达到一万的倍数就显示下级,比如9999万、9999亿、9999兆、1京以此类推 怪物血量显示也改成: 怪物血量剩余:9999万(00.00%)、9999亿(00.00%)、1兆(00.00%) 以此类推 //1200 2. 游戏: 点击游戏商城旁边的【解卡】按钮,让解卡功能可以生效,屏蔽掉弹出的聊天室 然后解卡的头顶信息显示加上人物的 伤害加成:、段伤次数:、切割伤害:、鞭尸几率: 切割伤害: 以万为进制单位 9999万 1亿 9999亿 1兆 和上面的血量一个概念的显示 //显示能做 150 3. 游戏: 游戏中攻击状态或者受伤状态人物会弯腰,这导致不能换装备不能丢道具进商城等一系列的限制,而且还弹窗恶心人 直接把这些限制禁止去掉,战斗状态或受伤的情况下可以进行所有操作 //服务端无法解决 4. 控制台:游戏设置-宠吸功能,在 功能开关 这里的 特殊全宠物吸物开关下面 增加一个开关 【boss支持吸金吸物开关】 就是说打死boss宠物也可以吸金吸物,目前boss是不吸的,同时哪怕打开了这个功能,如果地图代码是在不支持吸金吸物的表中,那肯定也不能吸 //功能150 开关你来 5. 控制台:定制功能里增加:1.多倍金币爆率表 2.多倍物品爆率表 3.金币+爆物双支持表,能支持写时间段和不限制时间段触发、不同道具是否支持叠加效果,可以用0/1区分,不需要道具数量叠加效果 源码搜索:5360018 看一下,原来的是写死在源码里的,如果同时拥有多个不同倍率的,增加个开关【不同倍率是否叠加】,不叠加就取最大值生效 //功能400 6. 控制台:定制功能里增加:鞭尸功能。。 就是传奇的鞭尸功能,玩家背包拥有某道具,道具数量越多几率越高,击杀怪物后,能让他再爆一遍,支持生效多倍爆率 这个功能在订制栏里面,增加个功能开关,增加个小一点的表,填道具 数量 几率 几率就按 1/10000 算吧 10000等于100% 触发鞭尸后,聊天框全服能看到的喇叭消息提示:恭喜[玩家名]在地图名字击杀怪物后触发鞭尸,怪物二次大爆! 这个功能需要能让js调用到函数,我可以显示在NPC上面,比如: 鞭尸几率:0.01% //功能400 7. 服务端: 启动工具的cmd不要呼出来 ,关闭服务端不需要重新打开,直接可以点击启动服务端 //你来研究下看看 我之前没弄出来 8. 服务端:服务端控制台-玩家控制台-后台工具-爆物管理 这里搞得人性化一点 归类到我自己的栏目里 之前的删掉或者屏蔽掉 可以点击上方的序号 怪物 名字 id 爆率 进行升降排序 显示出怪物ID对应的是什么怪物名字、能模糊搜怪物名、道具名,全部显示出来直接进行操作 可以直接在表上选取进行操作,能全部选取或者ctrl针对选取进行批量操作 添加爆率能直接搞个编辑框,按格式导入;同时能按导入格式导出 //ui 你来把 9. 游戏: 战力后面带 转生等级 显示 目前只显示战力 需要做成: 战力:123456 [转生次数0次] 这个 转生次数*次 自己可以在后台定义 比如给他改成 筑基*层 多少次转生显示什么在后台设置 比如转生100次= 金丹0层 那101次肯定不需要设置了对吧 直接显示 金丹1层 200次= 元婴0层 后面没增加新的话 就元婴1层 2层以此类推了 功能有开关,关闭的状态下只显示战力!打开的情况下显示在战力后面,我有其他端的截图,需要的时候给你看图 ★同时给战力修一下 玩家在脱穿装备的时候就即时更新战力,目前是需要切换频道的时候才能更新战力 //不知道转生功能是否已经有了 有了的话200 切换频道不知道麻不麻烦 不麻烦的话100 11. 游戏里有个偷学NPC,学了技能要切换频道才能显示,能不能改成学了技能就能显示 //估计是没办法的
2025-03-11 17:39:50 +08:00
equip.setqg(rs.getString("qg"));
2025-03-03 15:16:22 +08:00
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());
1 游戏: 给【怪物血量】和【服务端计算伤害】突破long的限制(9223372036854775807)目前最高922京,可以用测试伤害那个脚本测试,脚本里面改怪物血量 (万 、亿 、兆、 京 、垓、秭、穰、沟、涧、正、载、极、恒河沙、阿僧祗、那由他、不可思议、无量、大数、古戈尔、频菠萝、矜羯罗、不可说不可说转、超限数、绝对无限、绝对无量、绝对小数、绝对大数、绝对超限数) 总共28个单位,每个单位是前一个单位的1万倍 同时人物头顶的信息显示也要显示,每达到一万的倍数就显示下级,比如9999万、9999亿、9999兆、1京以此类推 怪物血量显示也改成: 怪物血量剩余:9999万(00.00%)、9999亿(00.00%)、1兆(00.00%) 以此类推 //1200 2. 游戏: 点击游戏商城旁边的【解卡】按钮,让解卡功能可以生效,屏蔽掉弹出的聊天室 然后解卡的头顶信息显示加上人物的 伤害加成:、段伤次数:、切割伤害:、鞭尸几率: 切割伤害: 以万为进制单位 9999万 1亿 9999亿 1兆 和上面的血量一个概念的显示 //显示能做 150 3. 游戏: 游戏中攻击状态或者受伤状态人物会弯腰,这导致不能换装备不能丢道具进商城等一系列的限制,而且还弹窗恶心人 直接把这些限制禁止去掉,战斗状态或受伤的情况下可以进行所有操作 //服务端无法解决 4. 控制台:游戏设置-宠吸功能,在 功能开关 这里的 特殊全宠物吸物开关下面 增加一个开关 【boss支持吸金吸物开关】 就是说打死boss宠物也可以吸金吸物,目前boss是不吸的,同时哪怕打开了这个功能,如果地图代码是在不支持吸金吸物的表中,那肯定也不能吸 //功能150 开关你来 5. 控制台:定制功能里增加:1.多倍金币爆率表 2.多倍物品爆率表 3.金币+爆物双支持表,能支持写时间段和不限制时间段触发、不同道具是否支持叠加效果,可以用0/1区分,不需要道具数量叠加效果 源码搜索:5360018 看一下,原来的是写死在源码里的,如果同时拥有多个不同倍率的,增加个开关【不同倍率是否叠加】,不叠加就取最大值生效 //功能400 6. 控制台:定制功能里增加:鞭尸功能。。 就是传奇的鞭尸功能,玩家背包拥有某道具,道具数量越多几率越高,击杀怪物后,能让他再爆一遍,支持生效多倍爆率 这个功能在订制栏里面,增加个功能开关,增加个小一点的表,填道具 数量 几率 几率就按 1/10000 算吧 10000等于100% 触发鞭尸后,聊天框全服能看到的喇叭消息提示:恭喜[玩家名]在地图名字击杀怪物后触发鞭尸,怪物二次大爆! 这个功能需要能让js调用到函数,我可以显示在NPC上面,比如: 鞭尸几率:0.01% //功能400 7. 服务端: 启动工具的cmd不要呼出来 ,关闭服务端不需要重新打开,直接可以点击启动服务端 //你来研究下看看 我之前没弄出来 8. 服务端:服务端控制台-玩家控制台-后台工具-爆物管理 这里搞得人性化一点 归类到我自己的栏目里 之前的删掉或者屏蔽掉 可以点击上方的序号 怪物 名字 id 爆率 进行升降排序 显示出怪物ID对应的是什么怪物名字、能模糊搜怪物名、道具名,全部显示出来直接进行操作 可以直接在表上选取进行操作,能全部选取或者ctrl针对选取进行批量操作 添加爆率能直接搞个编辑框,按格式导入;同时能按导入格式导出 //ui 你来把 9. 游戏: 战力后面带 转生等级 显示 目前只显示战力 需要做成: 战力:123456 [转生次数0次] 这个 转生次数*次 自己可以在后台定义 比如给他改成 筑基*层 多少次转生显示什么在后台设置 比如转生100次= 金丹0层 那101次肯定不需要设置了对吧 直接显示 金丹1层 200次= 元婴0层 后面没增加新的话 就元婴1层 2层以此类推了 功能有开关,关闭的状态下只显示战力!打开的情况下显示在战力后面,我有其他端的截图,需要的时候给你看图 ★同时给战力修一下 玩家在脱穿装备的时候就即时更新战力,目前是需要切换频道的时候才能更新战力 //不知道转生功能是否已经有了 有了的话200 切换频道不知道麻不麻烦 不麻烦的话100 11. 游戏里有个偷学NPC,学了技能要切换频道才能显示,能不能改成学了技能就能显示 //估计是没办法的
2025-03-11 17:39:50 +08:00
pse.setString(30, equip.getqg());
2025-03-03 15:16:22 +08:00
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;
}
}