package handling.channel.handler;
import client.BuddyList;
import client.BuddylistEntry;
import client.CharacterNameAndId;
import client.MapleCharacter;
import client.MapleClient;
import database.DatabaseConnection;
import handling.channel.ChannelServer;
import handling.world.WorldBuddyService;
import handling.world.WorldFindService;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import tools.data.input.SeekableLittleEndianAccessor;
import tools.packet.BuddyListPacket;
public class BuddyListHandler {
private static CharacterIdNameBuddyCapacity getCharacterIdAndNameFromDatabase(String name, String group)
throws SQLException {
CharacterIdNameBuddyCapacity ret;
try (PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("SELECT * FROM characters WHERE name LIKE ?")) {
ps.setString(1, name);
try (ResultSet rs = ps.executeQuery()) {
ret = null;
if ((rs.next()) && (rs.getInt("gm") < 3)) {
ret = new CharacterIdNameBuddyCapacity(rs.getInt("id"), rs.getString("name"), group, rs.getInt("buddyCapacity"));
}
}
ps.close();
}
return ret;
}
public static void BuddyOperation(SeekableLittleEndianAccessor slea, MapleClient c) {
int mode = slea.readByte();
BuddyList buddylist = c.getPlayer().getBuddylist();
/*
0x15 好友满
0x16 对方好友满
0x17 已是好友
0x18 已申请账号好友
0x19 等待通过好友申请
0x1C 角色不存在
*/
if (mode == 1) {//添加好友
String addName = slea.readMapleAsciiString();
String groupName = slea.readMapleAsciiString();
String remark = slea.readMapleAsciiString();
String alias = null;
if (slea.readByte() == 1) {
alias = slea.readMapleAsciiString();
}
if (alias != null) {
c.getPlayer().dropMessage(1, "暂时不支持账号综合好友的功能。");
return;
}
BuddylistEntry ble = buddylist.get(addName);
if (addName.getBytes().length > 13 || groupName.getBytes().length > 16 || (alias != null && alias.getBytes().length > 13) || remark.getBytes().length > 133) {
return;
}
if ((ble != null) && ((ble.getGroup().equals(groupName)) || (!ble.isVisible()))) {
c.getSession().write(BuddyListPacket.buddylistMessage(alias != null ? 0x18 : 0x19));
} else if ((ble != null) && (ble.isVisible())) {
ble.setGroup(groupName);
c.getSession().write(BuddyListPacket.updateBuddylist(buddylist.getBuddies(), 0x11, false, c.getPlayer().getId()));
} else if (buddylist.isFull()) {
c.getSession().write(BuddyListPacket.buddylistMessage(0x15));
} else {
try {
CharacterIdNameBuddyCapacity charWithId = null;
int channel = WorldFindService.getInstance().findChannel(addName);
if (channel > 0) {
MapleCharacter otherChar = ChannelServer.getInstance(channel).getPlayerStorage().getCharacterByName(addName);
if (otherChar == null) {
charWithId = getCharacterIdAndNameFromDatabase(addName, groupName);
} else if ((!otherChar.isIntern()) || (c.getPlayer().isIntern())) {
charWithId = new CharacterIdNameBuddyCapacity(otherChar.getId(), otherChar.getName(), groupName, otherChar.getBuddylist().getCapacity());
}
} else {
charWithId = getCharacterIdAndNameFromDatabase(addName, groupName);
}
if (charWithId != null) {
BuddyList.BuddyAddResult buddyAddResult = null;
//被加方处理
if (channel > 0) {
buddyAddResult = WorldBuddyService.getInstance().requestBuddyAdd(addName, c.getChannel(), c.getPlayer().getId(), c.getPlayer().getName(), c.getPlayer().getLevel(), c.getPlayer().getJob());
MapleCharacter chr = ChannelServer.getInstance(channel).getPlayerStorage().getCharacterByName(addName);
chr.getClient().getSession().write(BuddyListPacket.requestBuddylistAdd(c.getPlayer().getId(), c.getPlayer().getName(), -1));
} else {
Connection con = DatabaseConnection.getConnection();
PreparedStatement ps = con.prepareStatement("SELECT COUNT(*) as buddyCount FROM buddies WHERE characterid = ? AND pending = 0");
ps.setInt(1, charWithId.getId());
ResultSet rs = ps.executeQuery();
if (!rs.next()) {
ps.close();
rs.close();
throw new RuntimeException("Result set expected");
}
int count = rs.getInt("buddyCount");
if (count >= charWithId.getBuddyCapacity()) {
buddyAddResult = BuddyList.BuddyAddResult.好友列表已满;
}
rs.close();
ps.close();
ps = con.prepareStatement("SELECT pending FROM buddies WHERE characterid = ? AND buddyid = ?");
ps.setInt(1, charWithId.getId());
ps.setInt(2, c.getPlayer().getId());
rs = ps.executeQuery();
if (rs.next()) {
buddyAddResult = BuddyList.BuddyAddResult.已经是好友关系;
}
rs.close();
ps.close();
}
//加好友方处理
if (buddyAddResult == BuddyList.BuddyAddResult.好友列表已满) {//对方好友列表已满
c.getSession().write(BuddyListPacket.buddylistMessage(0x16));//0x19-3
} else {
int displayChannel = -1;
int otherCid = charWithId.getId();
if ((buddyAddResult == BuddyList.BuddyAddResult.已经是好友关系) && (channel > 0)) {
displayChannel = channel;
notifyRemoteChannel(c, channel, otherCid, groupName, BuddyList.BuddyOperation.添加好友);
} else if (buddyAddResult != BuddyList.BuddyAddResult.已经是好友关系) {
Connection con = DatabaseConnection.getConnection();
try (PreparedStatement ps = con.prepareStatement("INSERT INTO buddies (`characterid`, `buddyid`, `groupname`, `pending`) VALUES (?, ?, ?, 1)")) {
ps.setInt(1, charWithId.getId());
ps.setInt(2, c.getPlayer().getId());
ps.setString(3, groupName);
ps.executeUpdate();
ps.close();
}
}
buddylist.put(new BuddylistEntry(charWithId.getName(), otherCid, groupName, displayChannel, true));
c.getSession().write(BuddyListPacket.requestBuddylistAdd(otherCid, charWithId.getName(), displayChannel));
//c.getSession().write(BuddyListPacket.updateBuddylist(buddylist.getBuddies(), 0x11, false, c.getPlayer().getId()));
c.getSession().write(BuddyListPacket.buddylistPrompt(0x14, charWithId.getName()));//向charWithId.getName()发送了好友申请。
}
} else {//角色不存在
c.getSession().write(BuddyListPacket.buddylistMessage(0x1C));//0x19+3
}
} catch (SQLException e) {
System.err.println("SQL THROW" + e);
}
}
} else if (mode == 2) {//同意添加好友
int otherCid = slea.readInt();
BuddylistEntry ble = buddylist.get(otherCid);
if (!buddylist.isFull() && ble != null && !ble.isVisible()) {
int channel = WorldFindService.getInstance().findChannel(otherCid);
buddylist.put(new BuddylistEntry(ble.getName(), otherCid, "未指定群组", channel, true));
c.getSession().write(BuddyListPacket.requestBuddylistAdd(otherCid, ble.getName(), channel));
//c.getSession().write(BuddyListPacket.updateBuddylist(buddylist.getBuddies(), 0x11, false, c.getPlayer().getId()));
notifyRemoteChannel(c, channel, otherCid, "未指定群组", BuddyList.BuddyOperation.添加好友);
} else {
c.getSession().write(BuddyListPacket.buddylistMessage(0x16));
}
} else if (mode == 4) {//删除好友
int otherCid = slea.readInt();
BuddylistEntry blz = buddylist.get(otherCid);
if ((blz != null) && (blz.isVisible())) {
notifyRemoteChannel(c, WorldFindService.getInstance().findChannel(otherCid), otherCid, blz.getGroup(), BuddyList.BuddyOperation.删除好友);
}
buddylist.remove(otherCid);
c.getSession().write(BuddyListPacket.updateBuddylist(null, 0x22, true, otherCid));
} else if (mode == 6) {//拒绝添加好友
int fromCid = slea.readInt();
buddylist.remove(fromCid);
c.getSession().write(BuddyListPacket.updateBuddylist(null, 0x22, true, fromCid));
MapleCharacter from = MapleCharacter.getOnlineCharacterById(fromCid);
if (from == null) {
return;
}
from.getBuddylist().remove(c.getPlayer().getId());
from.getClient().getSession().write(BuddyListPacket.updateBuddylist(null, 0x22, true, c.getPlayer().getId()));
from.getClient().getSession().write(BuddyListPacket.buddylistPrompt(0x29, c.getPlayer().getName()));//c.getPlayer().getName()拒绝了好友申请。
} else if (mode == 0xA) {//增加好友上限
int capacity = c.getPlayer().getBuddyCapacity();
if ((capacity >= 100) || (c.getPlayer().getMeso() < 50000)) {
c.getPlayer().dropMessage(1, "金币不足,或已扩充达到上限。包括基本格数在内,好友目录中只能加入100个好友。您当前的好友数量为: " + capacity);
} else {
int newcapacity = capacity + 5;
c.getPlayer().gainMeso(-50000, true, true);
c.getPlayer().setBuddyCapacity((byte) newcapacity);
}
} else {
System.err.println("未处理好友操作码:" + mode);
}
}
private static void notifyRemoteChannel(MapleClient c, int remoteChannel, int otherCid, String group, BuddyList.BuddyOperation operation) {
MapleCharacter player = c.getPlayer();
if (remoteChannel > 0) {
WorldBuddyService.getInstance().buddyChanged(otherCid, player.getId(), player.getName(), c.getChannel(), operation, group);
}
}
private static final class CharacterIdNameBuddyCapacity extends CharacterNameAndId {
private final int buddyCapacity;
public CharacterIdNameBuddyCapacity(int id, String name, String group, int buddyCapacity) {
super(id, name, group);
this.buddyCapacity = buddyCapacity;
}
public int getBuddyCapacity() {
return this.buddyCapacity;
}
}
}