package com.jonathan.citrus.network.world; import com.jonathan.citrus.WorldModule; import com.jonathan.citrus.network.Packet; import com.jonathan.citrus.network.PacketBuilder; import com.jonathan.citrus.network.Session; import com.jonathan.citrus.network.world.handler.DockedPlayer; import com.jonathan.citrus.utility.Destroyable; import java.math.BigInteger; import java.nio.ByteBuffer; import java.util.HashMap; import java.util.Map; import java.util.Queue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; /** * Created by Jonathan on 12/21/13. */ public class LoginSession implements Destroyable, Runnable { private final Map worldDock = new HashMap(); private BlockingQueue currentSync; private Session session; private boolean connected = false; private boolean synch; public final Session getSession() { return session; } public final void setSession(Session session) { this.session = session; } //TODO might delete dunno public void init() { } @Override public void destroy() { if (!connected) { PacketBuilder pb = new PacketBuilder(); pb.putByte(10).putByte(WorldModule.getLogic().getId()).putByte(0).putString("127.0.0.1").putString(WorldModule.getLogic().getActivity()); ByteBuffer rsaBuffer = ByteBuffer.wrap(new BigInteger(pb.toPacket().getBytes()).modPow(WorldModule.getLogic().getExponent(), WorldModule.getLogic().getModulus()).toByteArray()); PacketBuilder tpb = new PacketBuilder(0); tpb.putByte(rsaBuffer.array().length); tpb.put(rsaBuffer.array()); session.write(tpb.toPacket()); } else { //write dc packet } } public void startSynchronize(int worldId, int flag, int playerCount, String address, String activity) { if (worldId == WorldModule.getLogic().getId()) { return; } DockedWorld d = new DockedWorld(worldId, flag, address, activity); d.setPredictedSize(playerCount); if (currentSync == null) { currentSync = new LinkedBlockingQueue(); } worldDock.put(worldId, d); } public void editDockedPlayer(int world, int globalIndex, int editCode) { if (synch) { boolean removeFromQueue = !worldDock.get(world).hasPlayer(globalIndex); if (removeFromQueue) { System.out.println("CURRENT SYNC REMOVAL CALLED"); currentSync.add(new DockedPlayer(globalIndex, "", 3)); //will never happen? //TODO we gotta find how to tell what players are friends with this faggot? //OH WAIT, people load their friendslists with the name and globalIndex, and when we add him //we alert players with this friend that the nigger is online. gg } } else { if (editCode == 0) { worldDock.get(world).removePlayer(globalIndex); } else { worldDock.get(world).setPlayerPrivateDetails(globalIndex, editCode); } } } //TODO apply to main loop public void setSynch(boolean sync) { this.synch = sync; this.currentSync = sync ? new LinkedBlockingQueue() : null; } public void applyQueue(Packet packet) { int amtThisRound = packet.get(); boolean finalSync = (amtThisRound & 0x4) == 0; // for(DockedPlayer player : players) { // currentSync.add(player); // } //TODO just add straight to the map, players removed while syncing will be added to the queue now. } @Override public void run() { if (synch) { //append queue etc } } public Packet toPacket() { PacketBuilder pb2 = new PacketBuilder(); pb2.putShort(worldDock.size() + 1); DockedWorld w; for (int i = 1; i < worldDock.size() + 2; i++) { pb2.putShort(i | 0x8000); if (i == WorldModule.getLogic().getId()) { //TODO load address through config. pb2.putString("127.0.0.1").putString(WorldModule.getLogic().getActivity()).putByte(0).putShort(WorldModule.getLogic().getPlayers().size()); } else { w = worldDock.get(i); pb2.putString(w.getAddress()).putString(w.getActivity()).putByte(w.getFlag()).putShort(synch ? w.getPredictedSize() : w.getPlayers()); //TODO we might just send -1 instead of predicted size. } } return pb2.toPacket(); } }