// Decompiled by Jad v1.5.7f. Copyright 2000 Pavel Kouznetsov.
// Jad home page: http://www.geocities.com/SiliconValley/Bridge/8617/jad.html
// Decompiler options: packimports(3) 
// Source File Name:   Connection.java

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Hashtable;
import java.util.StringTokenizer;

class Connection extends Thread
{

    Connection(Skrabble skrabble, String s, String s1, int i)
    {
        ownTable = -1;
        flood = 8;
        pings = new Hashtable();
        pingId = 1;
        noError = true;
        it = new int[10];
        szk = skrabble;
        playerName = s1;
        serverName = s;
        port = i;
        (new Thread(this)).start();
    }

    void _acceptMove(int i, int j)
    {
        send(Integer.toString(13) + ' ' + i + ' ' + j + '\n');
    }

    void _alive()
    {
        send(Integer.toString(1) + '\n');
    }

    void _joinTable(int i)
    {
        send(Integer.toString(7) + ' ' + i + '\n');
    }

    void _kickMeOut()
    {
        send(Integer.toString(5) + '\n');
    }

    void _leaveTable(int i)
    {
        if(ownTable == i)
            ownTable = -1;
        send(Integer.toString(9) + ' ' + i + '\n');
    }

    void _moveExchange(int i, int j, int k, int ai[])
    {
        StringBuffer stringbuffer = new StringBuffer(Integer.toString(16) + ' ' + i + ' ' + j + ' ' + k + ' ' + ai.length);
        for(int l = 0; l < ai.length; l++)
            stringbuffer.append(' ').append(ai[l]);

        stringbuffer.append('\n');
        send(stringbuffer.toString());
    }

    void _moveOK(int i, int j, int k, int l, int ai[])
    {
        StringBuffer stringbuffer = new StringBuffer(Integer.toString(15) + ' ' + i + ' ' + j + ' ' + k + ' ' + l + ' ' + ai.length);
        for(int i1 = 0; i1 < ai.length; i1++)
            stringbuffer.append(' ').append(ai[i1]);

        stringbuffer.append('\n');
        send(stringbuffer.toString());
    }

    void _movePass(int i, int j, int k)
    {
        send(Integer.toString(17) + ' ' + i + ' ' + j + ' ' + k + '\n');
    }

    void _newTable(int i, int j)
    {
        send(Integer.toString(6) + ' ' + i + ' ' + j + '\n');
    }

    void _ping()
    {
        if(flood > 0)
        {
            long l = System.currentTimeMillis();
            pings.put(new Integer(pingId), new Long(l));
            send(Integer.toString(3) + ' ' + pingId + '\n');
            pingId++;
            flood--;
        } else
        {
            tablef.say(-1, 0, _German.FLOOD_PROTECTION);
        }
    }

    void _rejectMove(int i, int j)
    {
        send(Integer.toString(14) + ' ' + i + ' ' + j + '\n');
    }

    void _tableGameStart(int i, int j)
    {
        send(Integer.toString(12) + ' ' + i + ' ' + j + '\n');
    }

    void _tableSay(int i, int j, String s)
    {
        if(s.equalsIgnoreCase("/gc"))
        {
            System.gc();
            tablef.say(i, j, "*** gc");
        } else
        if(flood > 0)
        {
            send(Integer.toString(11) + ' ' + i + ' ' + j + '\n' + s + '\n');
            flood--;
        } else
        {
            tablef.say(i, j, _German.FLOOD_PROTECTION);
        }
    }

    void _timeoutGame(int i, int j, int k)
    {
        send(Integer.toString(19) + ' ' + i + ' ' + j + ' ' + k + '\n');
    }

    void _timeoutMove(int i, int j, int k)
    {
        send(Integer.toString(18) + ' ' + i + ' ' + j + ' ' + k + '\n');
    }

    void close()
    {
        if(tablef != null)
            tablef.getDisposed();
        noError = false;
        try
        {
            ino.close();
        }
        catch(Exception _ex) { }
        try
        {
            outo.close();
        }
        catch(Exception _ex) { }
        try
        {
            sock.close();
        }
        catch(Exception _ex) { }
        szk.connectionFailure(_German.CONNECTION_LOST);
    }

    void fillit(int i)
        throws Exception
    {
        for(int j = 0; j < i; j++)
            it[j] = Integer.parseInt(sto.nextToken());

    }

    int nextint()
        throws Exception
    {
        return Integer.parseInt(sto.nextToken());
    }

    public void run()
    {
        boolean flag = false;
        try
        {
            InetAddress inetaddress = InetAddress.getByName(serverName);
            sock = new Socket(inetaddress, port);
            sock.setSoTimeout(30000);
            sock.setTcpNoDelay(true);
            ino = new DataInputStream(sock.getInputStream());
            outo = new DataOutputStream(sock.getOutputStream());
            send(_German.VID + '\n' + playerName + '\n');
            String s = ino.readLine();
            if(s.equals("OVERCROWDED"))
            {
                flag = true;
                throw someException;
            }
            sto = new StringTokenizer(s);
            pid = nextint();
            boolean flag1 = Integer.parseInt(sto.nextToken()) > 0;
            int j = Integer.parseInt(sto.nextToken());
            String as1[] = new String[j];
            for(int k = 0; k < j; k++)
                as1[k] = ino.readLine();

            sto = new StringTokenizer(ino.readLine());
            int l = nextint();
            String as2[][] = new String[l][];
            int ai1[] = new int[l];
            for(int j2 = 0; j2 < l; j2++)
            {
                sto = new StringTokenizer(ino.readLine());
                ai1[j2] = nextint();
                int k2 = nextint();
                as2[j2] = new String[k2];
                for(int i3 = 0; i3 < k2; i3++)
                    as2[j2][i3] = ino.readLine();

            }

            sock.setSoTimeout(0);
            szk.connectionSuccess(this);
            tablef = new TableFrame(this, flag1, as1, ai1, as2);
        }
        catch(Exception _ex)
        {
            close();
            if(flag)
                szk.connectionFailure(_German.SERVER_OVERCROWDED);
            else
                szk.connectionFailure(_German.CONNECTION_FAILURE);
            return;
        }
        ConnectionKeeper connectionkeeper = new ConnectionKeeper(this, 5);
        int ai[] = null;
        int i = -1;
        String as[] = null;
        String s1 = null;
        Object obj = null;
        while(noError) 
        {
            try
            {
                String s2 = ino.readLine();
                sto = new StringTokenizer(s2);
                i = nextint();
            }
            catch(Exception _ex)
            {
                noError = false;
            }
            if(noError)
                switch(i)
                {
                case 1: // '\001'
                default:
                    break;

                case 21: // '\025'
                    try
                    {
                        fillit(2);
                        s1 = ino.readLine();
                    }
                    catch(Exception _ex)
                    {
                        noError = false;
                    }
                    if(noError)
                        tablef.say(it[0], it[1], s1);
                    break;

                case 19: // '\023'
                case 20: // '\024'
                    try
                    {
                        fillit(2);
                    }
                    catch(Exception _ex)
                    {
                        noError = false;
                    }
                    if(noError)
                        tablef.moveAccepted(it[0], it[1], i == 19);
                    break;

                case 16: // '\020'
                    try
                    {
                        fillit(3);
                    }
                    catch(Exception _ex)
                    {
                        noError = false;
                    }
                    if(noError)
                        tablef.gameNewTime(it[0], it[1], it[2]);
                    break;

                case 15: // '\017'
                    try
                    {
                        fillit(3);
                        ai = new int[it[2]];
                        for(int i1 = 0; i1 < it[2]; i1++)
                            ai[i1] = nextint();

                    }
                    catch(Exception _ex)
                    {
                        noError = false;
                    }
                    if(noError)
                        tablef.gameMoveProp(it[0], it[1], ai);
                    break;

                case 18: // '\022'
                    try
                    {
                        fillit(3);
                        ai = new int[it[2]];
                        for(int j1 = 0; j1 < it[2]; j1++)
                            ai[j1] = nextint();

                    }
                    catch(Exception _ex)
                    {
                        noError = false;
                    }
                    if(noError)
                        tablef.newBricks(it[0], it[1], ai);
                    break;

                case 17: // '\021'
                    try
                    {
                        fillit(4);
                    }
                    catch(Exception _ex)
                    {
                        noError = false;
                    }
                    if(noError)
                        tablef.gameNewPoints(it[0], it[1], it[2], it[3]);
                    break;

                case 26: // '\032'
                    try
                    {
                        fillit(3);
                        ai = new int[it[2] * 2];
                        for(int k1 = 0; k1 < it[2]; k1++)
                        {
                            ai[k1 * 2 + 0] = nextint();
                            ai[k1 * 2 + 1] = nextint();
                        }

                        as = new String[it[2]];
                        for(int l1 = 0; l1 < it[2]; l1++)
                            as[l1] = ino.readLine();

                    }
                    catch(Exception _ex)
                    {
                        noError = false;
                    }
                    if(noError)
                        tablef.gameStart(it[0], it[1], it[2], as, ai);
                    break;

                case 23: // '\027'
                    try
                    {
                        fillit(5);
                        if(it[4] == 0)
                            ownTable = it[0];
                        as = new String[it[4]];
                        for(int i2 = 0; i2 < it[4]; i2++)
                            as[i2] = ino.readLine();

                    }
                    catch(Exception _ex)
                    {
                        noError = false;
                    }
                    if(noError)
                        tablef.tableStart(it[0], it[1], as, it[2], it[3]);
                    break;

                case 11: // '\013'
                    try
                    {
                        fillit(4);
                    }
                    catch(Exception _ex)
                    {
                        noError = false;
                    }
                    if(noError)
                        tablef.gameMover(it[0], it[1], it[2], it[3]);
                    break;

                case 10: // '\n'
                    try
                    {
                        fillit(2);
                    }
                    catch(Exception _ex)
                    {
                        noError = false;
                    }
                    if(noError)
                        tablef.gameOver(it[0], it[1]);
                    break;

                case 24: // '\030'
                    try
                    {
                        fillit(2);
                    }
                    catch(Exception _ex)
                    {
                        noError = false;
                    }
                    if(noError)
                        tablef.tableStop(it[0], it[1]);
                    break;

                case 27: // '\033'
                    try
                    {
                        fillit(3);
                        s1 = ino.readLine();
                    }
                    catch(Exception _ex)
                    {
                        noError = false;
                    }
                    if(noError)
                        tablef.tableJoin(it[0], it[1], s1, it[2]);
                    break;

                case 29: // '\035'
                    try
                    {
                        fillit(3);
                    }
                    catch(Exception _ex)
                    {
                        noError = false;
                    }
                    if(noError)
                        tablef.tableLeave(it[0], it[1], it[2]);
                    break;

                case 5: // '\005'
                    try
                    {
                        s1 = ino.readLine();
                    }
                    catch(Exception _ex)
                    {
                        noError = false;
                    }
                    if(noError)
                        tablef.addPlayer(s1);
                    break;

                case 6: // '\006'
                    try
                    {
                        s1 = ino.readLine();
                    }
                    catch(Exception _ex)
                    {
                        noError = false;
                    }
                    if(noError)
                        tablef.removePlayer(s1);
                    break;

                case 7: // '\007'
                    tablef.tableCreationAllowance(true);
                    break;

                case 8: // '\b'
                    tablef.tableCreationAllowance(false);
                    break;

                case 22: // '\026'
                    try
                    {
                        fillit(3);
                        s1 = ino.readLine();
                    }
                    catch(Exception _ex)
                    {
                        noError = false;
                    }
                    if(noError)
                        tablef.tableHost(it[0], it[1], it[2], s1);
                    break;

                case 2: // '\002'
                    try
                    {
                        it[0] = nextint();
                    }
                    catch(Exception _ex)
                    {
                        noError = false;
                    }
                    if(noError)
                    {
                        long l2 = System.currentTimeMillis();
                        Object obj1 = pings.get(new Integer(it[0]));
                        long l3 = l2 - ((Long)obj1).longValue();
                        pings.remove(new Integer(it[0]));
                        tablef.say(-1, 0, "*** " + _German.CONNECTION_PING + (double)l3 / 1000D + "s");
                    }
                    break;
                }
        }
        connectionkeeper.itself = null;
        close();
    }

    void send(String s)
    {
        if(noError)
            try
            {
                outo.writeBytes(s);
            }
            catch(IOException _ex)
            {
                noError = false;
            }
    }

    static final int CPACKET_FREQ = 5;
    static final Exception someException = new Exception();
    int pid;
    int ownTable;
    int flood;
    Hashtable pings;
    String serverName;
    int port;
    String playerName;
    StringTokenizer sto;
    int pingId;
    Skrabble szk;
    TableFrame tablef;
    Socket sock;
    DataInputStream ino;
    DataOutputStream outo;
    boolean noError;
    int it[];

}
