package javastory.channel.rmi; import java.rmi.RemoteException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Collection; import java.util.Collections; import java.util.List; import com.google.common.collect.Lists; import javastory.channel.ChannelCharacter; import javastory.channel.ChannelServer; import javastory.channel.CharacterTransfer; import javastory.channel.GuildSummary; import javastory.channel.Messenger; import javastory.channel.MessengerMember; import javastory.channel.Party; import javastory.channel.PartyMember; import javastory.channel.client.BuddyAddResult; import javastory.channel.client.BuddyList; import javastory.channel.client.BuddyListEntry; import javastory.channel.client.BuddyOperation; import javastory.channel.client.MemberRank; import javastory.config.ChannelInfo; import javastory.db.Database; import javastory.io.GamePacket; import javastory.rmi.ChannelWorldInterface; import javastory.rmi.GenericRemoteObject; import javastory.server.channel.PlayerStorage; import javastory.tools.CollectionUtil; import javastory.tools.packets.ChannelPackets; import javastory.world.core.CheaterData; import javastory.world.core.PartyOperation; public class ChannelWorldInterfaceImpl extends GenericRemoteObject implements ChannelWorldInterface { private static final long serialVersionUID = 7815256899088644192L; private final ChannelServer server; public ChannelWorldInterfaceImpl(final ChannelServer server) throws RemoteException { super(); this.server = server; } @Override public int getChannelId() throws RemoteException { return this.server.getChannelId(); } @Override public ChannelInfo getChannelInfo() throws RemoteException { return this.server.getChannelInfo(); } @Override public String getIP() throws RemoteException { return this.server.getIP(); } @Override public void broadcastMessage(final GamePacket packet) throws RemoteException { this.server.broadcastPacket(packet); } @Override public void broadcastSmega(final GamePacket packet) throws RemoteException { this.server.broadcastSmegaPacket(packet); } @Override public void broadcastGMMessage(final GamePacket packet) throws RemoteException { this.server.broadcastGMPacket(packet); } @Override public void whisper(final String sender, final String target, final int channel, final String message) throws RemoteException { if (this.isConnected(target)) { ChannelServer.getPlayerStorage().getCharacterByName(target).getClient().write(ChannelPackets.getWhisper(sender, channel, message)); } } @Override public boolean isConnected(final String charName) throws RemoteException { return ChannelServer.getPlayerStorage().getCharacterByName(charName) != null; } @Override public boolean isCharacterListConnected(final List<String> charName) throws RemoteException { for (final String c : charName) { if (ChannelServer.getPlayerStorage().getCharacterByName(c) != null) { return true; } } return false; } @Override public void toggleMegaphoneMuteState() throws RemoteException { this.server.toggleMegaponeMuteState(); } @Override public boolean hasMerchant(final int accountId) throws RemoteException { return this.server.hasMerchant(accountId); } @Override public void shutdown(final int time) throws RemoteException { this.server.shutdown(time); } @Override public int getConnected() throws RemoteException { return ChannelServer.getPlayerStorage().getConnectedClients(); } @Override public void loggedOff(final String name, final int characterId, final int channel, final int[] buddies) throws RemoteException { this.updateBuddies(characterId, channel, buddies, true); } @Override public void loggedOn(final String name, final int characterId, final int channel, final int buddies[]) throws RemoteException { this.updateBuddies(characterId, channel, buddies, false); } private void updateBuddies(final int characterId, final int channel, final int[] buddies, final boolean offline) { final PlayerStorage playerStorage = ChannelServer.getPlayerStorage(); for (final int buddy : buddies) { final ChannelCharacter chr = playerStorage.getCharacterById(buddy); if (chr != null) { final BuddyListEntry ble = chr.getBuddyList().get(characterId); if (ble != null && ble.isVisible()) { int mcChannel; if (offline) { ble.setChannel(-1); mcChannel = -1; } else { ble.setChannel(channel); mcChannel = channel - 1; } chr.getBuddyList().put(ble); chr.getClient().write(ChannelPackets.updateBuddyChannel(ble.getCharacterId(), mcChannel)); } } } } @Override public void updateParty(final Party party, final PartyOperation operation, final PartyMember target) throws RemoteException { for (final PartyMember partychar : party.getMembers()) { if (partychar.getChannel() == this.server.getChannelId()) { final ChannelCharacter chr = ChannelServer.getPlayerStorage().getCharacterByName(partychar.getName()); if (chr != null) { if (operation == PartyOperation.DISBAND) { chr.setParty(null); } else { chr.setParty(party); } chr.getClient().write(ChannelPackets.updateParty(chr.getClient().getChannelId(), party, operation, target)); } } } switch (operation) { case LEAVE: case EXPEL: if (target.getChannel() == this.server.getChannelId()) { final ChannelCharacter chr = ChannelServer.getPlayerStorage().getCharacterByName(target.getName()); if (chr != null) { chr.getClient().write(ChannelPackets.updateParty(chr.getClient().getChannelId(), party, operation, target)); chr.setParty(null); } } } } @Override public void partyChat(final Party party, final String chattext, final String namefrom) throws RemoteException { for (final PartyMember partychar : party.getMembers()) { if (partychar.getChannel() == this.server.getChannelId() && !partychar.getName().equals(namefrom)) { final ChannelCharacter chr = ChannelServer.getPlayerStorage().getCharacterByName(partychar.getName()); if (chr != null) { chr.getClient().write(ChannelPackets.multiChat(namefrom, chattext, 1)); } } } } @Override public int getLocation(final String name) throws RemoteException { final ChannelCharacter chr = ChannelServer.getPlayerStorage().getCharacterByName(name); if (chr != null) { return chr.getMapId(); } return -1; } @Override public List<CheaterData> getCheaters() throws RemoteException { final List<CheaterData> cheaters = ChannelServer.getPlayerStorage().getCheaters(); Collections.sort(cheaters); return CollectionUtil.copyFirst(cheaters, 20); } @Override public BuddyAddResult requestBuddyAdd(final String addName, final int channelFrom, final int cidFrom, final String nameFrom, final int levelFrom, final int jobFrom) { final ChannelCharacter addChar = ChannelServer.getPlayerStorage().getCharacterByName(addName); if (addChar != null) { final BuddyList buddylist = addChar.getBuddyList(); if (buddylist.isFull()) { return BuddyAddResult.BUDDYLIST_FULL; } if (!buddylist.contains(cidFrom)) { buddylist.addBuddyRequest(addChar.getClient(), cidFrom, nameFrom, channelFrom, levelFrom, jobFrom); } else { if (buddylist.containsVisible(cidFrom)) { return BuddyAddResult.ALREADY_ON_LIST; } } } return BuddyAddResult.OK; } @Override public boolean isConnected(final int characterId) throws RemoteException { return ChannelServer.getPlayerStorage().getCharacterById(characterId) != null; } @Override public void buddyChanged(final int cid, final int cidFrom, final String name, final int channel, final BuddyOperation operation, final int level, final int job) { final ChannelCharacter addChar = ChannelServer.getPlayerStorage().getCharacterById(cid); if (addChar != null) { final BuddyList buddylist = addChar.getBuddyList(); switch (operation) { case ADDED: if (buddylist.contains(cidFrom)) { buddylist.put(new BuddyListEntry(name, cidFrom, "ETC", channel, true, level, job)); addChar.getClient().write(ChannelPackets.updateBuddyChannel(cidFrom, channel - 1)); } break; case DELETED: if (buddylist.contains(cidFrom)) { buddylist.put(new BuddyListEntry(name, cidFrom, "ETC", -1, buddylist.get(cidFrom).isVisible(), level, job)); addChar.getClient().write(ChannelPackets.updateBuddyChannel(cidFrom, -1)); } break; } } } @Override public void buddyChat(final int[] recipientCharacterIds, final int cidFrom, final String nameFrom, final String chattext) throws RemoteException { final PlayerStorage playerStorage = ChannelServer.getPlayerStorage(); for (final int characterId : recipientCharacterIds) { final ChannelCharacter chr = playerStorage.getCharacterById(characterId); if (chr != null) { if (chr.getBuddyList().containsVisible(cidFrom)) { chr.getClient().write(ChannelPackets.multiChat(nameFrom, chattext, 0)); } } } } @Override public int[] multiBuddyFind(final int charIdFrom, final int[] characterIds) throws RemoteException { final List<Integer> ret = Lists.newArrayListWithCapacity(characterIds.length); final PlayerStorage playerStorage = ChannelServer.getPlayerStorage(); for (final int characterId : characterIds) { final ChannelCharacter chr = playerStorage.getCharacterById(characterId); if (chr != null) { if (chr.getBuddyList().containsVisible(charIdFrom)) { ret.add(characterId); } } } final int[] retArr = new int[ret.size()]; int pos = 0; for (final Integer i : ret) { retArr[pos++] = i.intValue(); } return retArr; } @Override public void ChannelChange_Data(final CharacterTransfer transfer, final int characterid) throws RemoteException { ChannelServer.getPlayerStorage().registerTransfer(transfer, characterid); } @Override public void sendPacket(final Collection<Integer> targetIds, final GamePacket packet, final int exception) throws RemoteException { ChannelCharacter c; for (final int i : targetIds) { if (i == exception) { continue; } c = ChannelServer.getPlayerStorage().getCharacterById(i); if (c != null) { c.getClient().write(packet); } } } @Override public void setGuildAndRank(final Collection<Integer> cids, final int guildid, final MemberRank rank, final int exception) throws RemoteException { for (final int cid : cids) { if (cid != exception) { this.setGuildAndRank(cid, guildid, rank); } } } @Override public void setGuildAndRank(final int cid, final int guildid, final MemberRank rank) throws RemoteException { final ChannelCharacter mc = ChannelServer.getPlayerStorage().getCharacterById(cid); if (mc == null) { // System.out.println("ERROR: cannot find player in given channel"); return; } boolean bDifferentGuild; if (guildid == -1 && rank == null) { //just need a respawn bDifferentGuild = true; } else { bDifferentGuild = guildid != mc.getGuildId(); mc.setGuildId(guildid); mc.setGuildRank(rank); mc.saveGuildStatus(); } if (bDifferentGuild) { mc.getMap().broadcastMessage(mc, ChannelPackets.removePlayerFromMap(cid), false); mc.getMap().broadcastMessage(mc, ChannelPackets.spawnPlayerMapObject(mc), false); } } @Override public void setOfflineGuildStatus(final int guildId, final MemberRank rank, final int cid) throws RemoteException { final Connection con = Database.getConnection(); try (PreparedStatement ps = con.prepareStatement("UPDATE characters SET guildid = ?, guildrank = ? WHERE id = ?")) { ps.setInt(1, guildId); ps.setInt(2, rank.asNumber()); ps.setInt(3, cid); ps.execute(); } catch (final SQLException se) { System.out.println("SQLException: " + se.getLocalizedMessage() + se); } } @Override public void changeEmblem(final int gid, final Collection<Integer> affectedPlayers, final GuildSummary mgs) throws RemoteException { ChannelServer.getInstance().updateGuildSummary(gid, mgs); this.sendPacket(affectedPlayers, ChannelPackets.guildEmblemChange(gid, mgs.getEmblem()), -1); this.setGuildAndRank(affectedPlayers, -1, null, -1); //respawn player } @Override public void messengerInvite(final String sender, final int messengerid, final String target, final int fromchannel) throws RemoteException { // TODO: No op. Finish when ChannelServer remoting is done. } @Override public void addMessengerPlayer(final Messenger messenger, final String namefrom, final int fromchannel, final int position) throws RemoteException { // TODO: No op. Finish when ChannelServer remoting is done. } @Override public void removeMessengerPlayer(final Messenger messenger, final int position) throws RemoteException { for (final MessengerMember messengerchar : messenger.getMembers()) { if (messengerchar.getChannel() == this.server.getChannelId()) { final ChannelCharacter chr = ChannelServer.getPlayerStorage().getCharacterByName(messengerchar.getName()); if (chr != null) { chr.getClient().write(ChannelPackets.removeMessengerPlayer(position)); } } } } @Override public void messengerChat(final Messenger messenger, final String chattext, final String namefrom) throws RemoteException { for (final MessengerMember messengerchar : messenger.getMembers()) { if (messengerchar.getChannel() == this.server.getChannelId() && !messengerchar.getName().equals(namefrom)) { final ChannelCharacter chr = ChannelServer.getPlayerStorage().getCharacterByName(messengerchar.getName()); if (chr != null) { chr.getClient().write(ChannelPackets.messengerChat(chattext)); } } } } @Override public void declineChat(final String target, final String namefrom) throws RemoteException { if (this.isConnected(target)) { final ChannelCharacter chr = ChannelServer.getPlayerStorage().getCharacterByName(target); final Messenger messenger = chr.getMessenger(); if (messenger != null) { chr.getClient().write(ChannelPackets.messengerNote(namefrom, 5, 0)); } } } @Override public void updateMessenger(final Messenger messenger, final String namefrom, final int position, final int fromchannel) throws RemoteException { // TODO: No op. Finish when ChannelServer remoting is done. } }