Browse Source

threadless client (for web)

master
Mister Hat 3 months ago
parent
commit
5583ddff51
26 changed files with 20125 additions and 0 deletions
  1. +513
    -0
      mudclient204-threadless/BZLib.java
  2. +70
    -0
      mudclient204-threadless/BZState.java
  3. +79
    -0
      mudclient204-threadless/Buffer.java
  4. +101
    -0
      mudclient204-threadless/ChatMessage.java
  5. +130
    -0
      mudclient204-threadless/ClientStream.java
  6. +133
    -0
      mudclient204-threadless/Command.java
  7. +47
    -0
      mudclient204-threadless/GameCharacter.java
  8. +544
    -0
      mudclient204-threadless/GameConnection.java
  9. +474
    -0
      mudclient204-threadless/GameData.java
  10. +64
    -0
      mudclient204-threadless/GameFrame.java
  11. +1031
    -0
      mudclient204-threadless/GameModel.java
  12. +565
    -0
      mudclient204-threadless/GameShell.java
  13. +181
    -0
      mudclient204-threadless/ISAAC.java
  14. +266
    -0
      mudclient204-threadless/Packet.java
  15. +708
    -0
      mudclient204-threadless/Panel.java
  16. +25
    -0
      mudclient204-threadless/Polygon.java
  17. +10
    -0
      mudclient204-threadless/Scanline.java
  18. +3127
    -0
      mudclient204-threadless/Scene.java
  19. +6
    -0
      mudclient204-threadless/StreamAudioPlayer.java
  20. +2016
    -0
      mudclient204-threadless/Surface.java
  21. +32
    -0
      mudclient204-threadless/SurfaceSprite.java
  22. +238
    -0
      mudclient204-threadless/Utility.java
  23. +15
    -0
      mudclient204-threadless/Version.java
  24. +711
    -0
      mudclient204-threadless/WordFilter.java
  25. +1484
    -0
      mudclient204-threadless/World.java
  26. +7555
    -0
      mudclient204-threadless/mudclient.java

+ 513
- 0
mudclient204-threadless/BZLib.java View File

@ -0,0 +1,513 @@
public class BZLib {
public static int decompress(byte out[], int outSize, byte in[], int inSize, int offset) {
BZState block = new BZState();
block.input = in;
block.nextIn = offset;
block.output = out;
block.availOut = 0;
block.availIn = inSize;
block.decompressedSize = outSize;
block.bsLive = 0;
block.bsBuff = 0;
block.totalInLo32 = 0;
block.totalInHi32 = 0;
block.totalOutLo32 = 0;
block.totalOutHi32 = 0;
block.blockNo = 0;
decompress(block);
outSize -= block.decompressedSize;
return outSize;
}
private static void nextHeader(BZState state) {
byte cStateOutCh = state.stateOutCh;
int cStateOutLen = state.stateOutLen;
int cNblockUsed = state.nblockUsed;
int cK0 = state.k0;
int cTt[] = state.tt;
int cTpos = state.tpos;
byte output[] = state.output;
int csNextOut = state.availOut;
int csAvailOut = state.decompressedSize;
int asdasdasd = csAvailOut;
int sSaveNblockPP = state.saveNblock + 1;
returnNotr:
do {
if (cStateOutLen > 0) {
do {
if (csAvailOut == 0)
break returnNotr;
if (cStateOutLen == 1)
break;
output[csNextOut] = cStateOutCh;
cStateOutLen--;
csNextOut++;
csAvailOut--;
} while (true);
if (csAvailOut == 0) {
cStateOutLen = 1;
break;
}
output[csNextOut] = cStateOutCh;
csNextOut++;
csAvailOut--;
}
boolean flag = true;
while (flag) {
flag = false;
if (cNblockUsed == sSaveNblockPP) {
cStateOutLen = 0;
break returnNotr;
}
cStateOutCh = (byte) cK0;
cTpos = cTt[cTpos];
byte k1 = (byte) (cTpos & 0xff);
cTpos >>= 8;
cNblockUsed++;
if (k1 != cK0) {
cK0 = k1;
if (csAvailOut == 0) {
cStateOutLen = 1;
} else {
output[csNextOut] = cStateOutCh;
csNextOut++;
csAvailOut--;
flag = true;
continue;
}
break returnNotr;
}
if (cNblockUsed != sSaveNblockPP)
continue;
if (csAvailOut == 0) {
cStateOutLen = 1;
break returnNotr;
}
output[csNextOut] = cStateOutCh;
csNextOut++;
csAvailOut--;
flag = true;
}
cStateOutLen = 2;
cTpos = cTt[cTpos];
byte k2 = (byte) (cTpos & 0xff);
cTpos >>= 8;
if (++cNblockUsed != sSaveNblockPP)
if (k2 != cK0) {
cK0 = k2;
} else {
cStateOutLen = 3;
cTpos = cTt[cTpos];
byte k3 = (byte) (cTpos & 0xff);
cTpos >>= 8;
if (++cNblockUsed != sSaveNblockPP)
if (k3 != cK0) {
cK0 = k3;
} else {
cTpos = cTt[cTpos];
byte byte3 = (byte) (cTpos & 0xff);
cTpos >>= 8;
cNblockUsed++;
cStateOutLen = (byte3 & 0xff) + 4;
cTpos = cTt[cTpos];
cK0 = (byte) (cTpos & 0xff);
cTpos >>= 8;
cNblockUsed++;
}
}
} while (true);
int i2 = state.totalOutLo32;
state.totalOutLo32 += asdasdasd - csAvailOut;
if (state.totalOutLo32 < i2)
state.totalOutHi32++;
state.stateOutCh = cStateOutCh;
state.stateOutLen = cStateOutLen;
state.nblockUsed = cNblockUsed;
state.k0 = cK0;
state.tt = cTt;
state.tpos = cTpos;
state.output = output;
state.availOut = csNextOut;
state.decompressedSize = csAvailOut;
}
private static void decompress(BZState state) {
/*boolean flag = false;
boolean flag1 = false;
boolean flag2 = false;
boolean flag3 = false;
boolean flag4 = false;
boolean flag5 = false;
boolean flag6 = false;
boolean flag7 = false;
boolean flag8 = false;
boolean flag9 = false;
boolean flag10 = false;
boolean flag11 = false;
boolean flag12 = false;
boolean flag13 = false;
boolean flag14 = false;
boolean flag15 = false;
boolean flag16 = false;
boolean flag17 = false;
boolean flag18 = false;*/
int gMinLen = 0;
int gLimit[] = null;
int gBase[] = null;
int gPerm[] = null;
state.blocksize100k = 1;
if (state.tt == null)
state.tt = new int[state.blocksize100k * 100000];
boolean goingandshit = true;
while (goingandshit) {
byte uc = getUchar(state);
if (uc == 23)
return;
uc = getUchar(state);
uc = getUchar(state);
uc = getUchar(state);
uc = getUchar(state);
uc = getUchar(state);
state.blockNo++;
uc = getUchar(state);
uc = getUchar(state);
uc = getUchar(state);
uc = getUchar(state);
uc = getBit(state);
state.blockRandomised = uc != 0;
if (state.blockRandomised)
System.out.println("PANIC! RANDOMISED BLOCK!");
state.origPtr = 0;
uc = getUchar(state);
state.origPtr = state.origPtr << 8 | uc & 0xff;
uc = getUchar(state);
state.origPtr = state.origPtr << 8 | uc & 0xff;
uc = getUchar(state);
state.origPtr = state.origPtr << 8 | uc & 0xff;
for (int i = 0; i < 16; i++) {
uc = getBit(state);
state.inUse_16[i] = uc == 1;
}
for (int i = 0; i < 256; i++)
state.inUse[i] = false;
for (int i = 0; i < 16; i++)
if (state.inUse_16[i]) {
for (int j = 0; j < 16; j++) {
uc = getBit(state);
if (uc == 1)
state.inUse[i * 16 + j] = true;
}
}
makeMaps(state);
int alphaSize = state.nInUse + 2;
int nGroups = getBits(3, state);
int nSelectors = getBits(15, state);
for (int i = 0; i < nSelectors; i++) {
int j = 0;
do {
uc = getBit(state);
if (uc == 0)
break;
j++;
} while (true);
state.selectorMtf[i] = (byte) j;
}
byte pos[] = new byte[6];
for (byte v = 0; v < nGroups; v++)
pos[v] = v;
for (int i = 0; i < nSelectors; i++) {
byte v = state.selectorMtf[i];
byte tmp = pos[v];
for (; v > 0; v--)
pos[v] = pos[v - 1];
pos[0] = tmp;
state.selector[i] = tmp;
}
for (int t = 0; t < nGroups; t++) {
int curr = getBits(5, state);
for (int i = 0; i < alphaSize; i++) {
do {
uc = getBit(state);
if (uc == 0)
break;
uc = getBit(state);
if (uc == 0)
curr++;
else
curr--;
} while (true);
state.len[t][i] = (byte) curr;
}
}
for (int t = 0; t < nGroups; t++) {
byte minLen = 32;
int maxLen = 0;
for (int l1 = 0; l1 < alphaSize; l1++) {
if (state.len[t][l1] > maxLen)
maxLen = state.len[t][l1];
if (state.len[t][l1] < minLen)
minLen = state.len[t][l1];
}
createDecodeTables(state.limit[t], state.base[t], state.perm[t], state.len[t], minLen, maxLen, alphaSize);
state.minLens[t] = minLen;
}
int eob = state.nInUse + 1;
int nblockMax = 100000 * state.blocksize100k;
int groupNo = -1;
int groupPos = 0;
for (int i = 0; i <= 255; i++)
state.unzftab[i] = 0;
int kk = 4095; // MTFASIZE-1;
for (int ii = 15; ii >= 0; ii--) {
for (int jj = 15; jj >= 0; jj--) {
state.mtfa[kk] = (byte) (ii * 16 + jj);
kk--;
}
state.mtfbase[ii] = kk + 1;
}
int nblock = 0;
// GETMTFVAL
if (groupPos == 0) {
groupNo++;
groupPos = 50; // BZGSIZE
byte gSel = state.selector[groupNo];
gMinLen = state.minLens[gSel];
gLimit = state.limit[gSel];
gPerm = state.perm[gSel];
gBase = state.base[gSel];
}
groupPos--;
int zn = gMinLen;
int zvec;
byte zj;
for (zvec = getBits(zn, state); zvec > gLimit[zn]; zvec = zvec << 1 | zj) {
zn++;
zj = getBit(state);
}
for (int nextSym = gPerm[zvec - gBase[zn]]; nextSym != eob; )
if (nextSym == 0 || nextSym == 1) { // BZRUNA, BZRUNB
int es = -1;
int N = 1;
do {
if (nextSym == 0)
es += N;
else if (nextSym == 1)
es += 2 * N;
N *= 2;
// GETMTFVAL, y da fuk did they not subroutine this
if (groupPos == 0) {
groupNo++;
groupPos = 50;
byte gSel = state.selector[groupNo];
gMinLen = state.minLens[gSel];
gLimit = state.limit[gSel];
gPerm = state.perm[gSel];
gBase = state.base[gSel];
}
groupPos--;
int zn_2 = gMinLen;
int zvec_2;
byte zj_2;
for (zvec_2 = getBits(zn_2, state); zvec_2 > gLimit[zn_2]; zvec_2 = zvec_2 << 1 | zj_2) {
zn_2++;
zj_2 = getBit(state);
}
nextSym = gPerm[zvec_2 - gBase[zn_2]];
} while (nextSym == 0 || nextSym == 1);
es++;
uc = state.setToUnseq[state.mtfa[state.mtfbase[0]] & 0xff];
state.unzftab[uc & 0xff] += es;
for (; es > 0; es--) {
state.tt[nblock] = uc & 0xff;
nblock++;
}
} else {
int nn = nextSym - 1;
if (nn < 16) { // MTFLSIZE
int pp = state.mtfbase[0];
uc = state.mtfa[pp + nn];
for (; nn > 3; nn -= 4) {
int z = pp + nn;
state.mtfa[z] = state.mtfa[z - 1];
state.mtfa[z - 1] = state.mtfa[z - 2];
state.mtfa[z - 2] = state.mtfa[z - 3];
state.mtfa[z - 3] = state.mtfa[z - 4];
}
for (; nn > 0; nn--)
state.mtfa[pp + nn] = state.mtfa[(pp + nn) - 1];
state.mtfa[pp] = uc;
} else {
int lno = nn / 16;
int off = nn % 16;
int pp = state.mtfbase[lno] + off;
uc = state.mtfa[pp];
for (; pp > state.mtfbase[lno]; pp--)
state.mtfa[pp] = state.mtfa[pp - 1];
state.mtfbase[lno]++;
for (; lno > 0; lno--) {
state.mtfbase[lno]--;
state.mtfa[state.mtfbase[lno]] = state.mtfa[(state.mtfbase[lno - 1] + 16) - 1];
}
state.mtfbase[0]--;
state.mtfa[state.mtfbase[0]] = uc;
if (state.mtfbase[0] == 0) {
kk = 4095; // MTFASIZE - 1
for (int ii = 15; ii >= 0; ii--) {
for (int jj = 15; jj >= 0; jj--) {
state.mtfa[kk] = state.mtfa[state.mtfbase[ii] + jj];
kk--;
}
state.mtfbase[ii] = kk + 1;
}
}
}
state.unzftab[state.setToUnseq[uc & 0xff] & 0xff]++;
state.tt[nblock] = state.setToUnseq[uc & 0xff] & 0xff;
nblock++;
// GETMTFVAL here we go AGAIN
if (groupPos == 0) {
groupNo++;
groupPos = 50;
byte gSel = state.selector[groupNo];
gMinLen = state.minLens[gSel];
gLimit = state.limit[gSel];
gPerm = state.perm[gSel];
gBase = state.base[gSel];
}
groupPos--;
int zn_2 = gMinLen;
int zvec_2;
byte zj_2;
for (zvec_2 = getBits(zn_2, state); zvec_2 > gLimit[zn_2]; zvec_2 = zvec_2 << 1 | zj_2) {
zn_2++;
zj_2 = getBit(state);
}
nextSym = gPerm[zvec_2 - gBase[zn_2]];
}
state.stateOutLen = 0;
state.stateOutCh = 0;
state.cftab[0] = 0;
for (int i = 1; i <= 256; i++)
state.cftab[i] = state.unzftab[i - 1];
for (int i = 1; i <= 256; i++)
state.cftab[i] += state.cftab[i - 1];
for (int i = 0; i < nblock; i++) {
uc = (byte) (state.tt[i] & 0xff);
state.tt[state.cftab[uc & 0xff]] |= i << 8;
state.cftab[uc & 0xff]++;
}
state.tpos = state.tt[state.origPtr] >> 8;
state.nblockUsed = 0;
state.tpos = state.tt[state.tpos];
state.k0 = (byte) (state.tpos & 0xff);
state.tpos >>= 8;
state.nblockUsed++;
state.saveNblock = nblock;
nextHeader(state);
goingandshit = state.nblockUsed == state.saveNblock + 1 && state.stateOutLen == 0;
}
}
private static byte getUchar(BZState state) {
return (byte) getBits(8, state);
}
private static byte getBit(BZState state) {
return (byte) getBits(1, state);
}
private static int getBits(int i, BZState state) {
int vvv;
do {
if (state.bsLive >= i) {
int v = state.bsBuff >> state.bsLive - i & (1 << i) - 1;
state.bsLive -= i;
vvv = v;
break;
}
state.bsBuff = state.bsBuff << 8 | state.input[state.nextIn] & 0xff;
state.bsLive += 8;
state.nextIn++;
state.availIn--;
state.totalInLo32++;
if (state.totalInLo32 == 0)
state.totalInHi32++;
} while (true);
return vvv;
}
private static void makeMaps(BZState state) {
state.nInUse = 0;
for (int i = 0; i < 256; i++)
if (state.inUse[i]) {
state.setToUnseq[state.nInUse] = (byte) i;
state.nInUse++;
}
}
private static void createDecodeTables(int limit[], int base[], int perm[], byte length[], int minLen, int maxLen, int alphaSize) {
int pp = 0;
for (int i = minLen; i <= maxLen; i++) {
for (int j = 0; j < alphaSize; j++)
if (length[j] == i) {
perm[pp] = j;
pp++;
}
}
for (int i = 0; i < 23; i++)
base[i] = 0;
for (int i = 0; i < alphaSize; i++)
base[length[i] + 1]++;
for (int i = 1; i < 23; i++)
base[i] += base[i - 1];
for (int i = 0; i < 23; i++)
limit[i] = 0;
int vec = 0;
for (int i = minLen; i <= maxLen; i++) {
vec += base[i + 1] - base[i];
limit[i] = vec - 1;
vec <<= 1;
}
for (int i = minLen + 1; i <= maxLen; i++)
base[i] = (limit[i - 1] + 1 << 1) - base[i];
}
}

+ 70
- 0
mudclient204-threadless/BZState.java View File

@ -0,0 +1,70 @@
class BZState {
//int anIntArray488[]; // unused
public int tt[]; // this was static, wonder why?
/* unused
int anInt456 = 4096; // MTFASIZE ?
int anInt457 = 16; // MTFLSIZE
int anInt458 = 258;
int anInt459 = 23;
int anInt460 = 1;
int anInt461 = 6; // BZNGROUPS ?
int anInt462 = 50; // BZGSIZE ?
int anInt463 = 4;
int anInt464 = 18002; */
byte input[];
int nextIn;
int availIn;
int totalInLo32;
int totalInHi32;
byte output[];
int availOut;
int decompressedSize;
int totalOutLo32;
int totalOutHi32;
byte stateOutCh;
int stateOutLen;
boolean blockRandomised;
int bsBuff;
int bsLive;
int blocksize100k;
int blockNo;
int origPtr;
int tpos;
int k0;
int unzftab[];
int nblockUsed;
int cftab[];
int nInUse;
boolean inUse[];
boolean inUse_16[];
byte setToUnseq[];
byte mtfa[];
int mtfbase[];
byte selector[];
byte selectorMtf[];
byte len[][];
int limit[][];
int base[][];
int perm[][];
int minLens[];
int saveNblock;
BZState() {
unzftab = new int[256];
cftab = new int[257];
//anIntArray488 = new int[257]; // unused
inUse = new boolean[256];
inUse_16 = new boolean[16];
setToUnseq = new byte[256];
mtfa = new byte[4096];
mtfbase = new int[16];
selector = new byte[18002];
selectorMtf = new byte[18002];
len = new byte[6][258];
limit = new int[6][258];
base = new int[6][258];
perm = new int[6][258];
minLens = new int[6];
}
}

+ 79
- 0
mudclient204-threadless/Buffer.java View File

@ -0,0 +1,79 @@
import java.math.BigInteger;
public class Buffer {
/*static CRC32 unusedCRC = new CRC32();
private static int unusedArray[] = {
0, 1, 3, 7, 15, 31, 63, 127, 255, 511,
1023, 2047, 4095, 8191, 16383, 32767, 65535, 0x1ffff, 0x3ffff, 0x7ffff,
0xfffff, 0x1fffff, 0x3fffff, 0x7fffff, 0xffffff, 0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff, 0x1fffffff,
0x3fffffff, 0x7fffffff, -1
};*/
public byte buffer[];
public int offset;
public Buffer(byte buff[]) {
buffer = buff;
offset = 0;
}
public void putByte(int i) {
buffer[offset++] = (byte) i;
}
public void putInt(int i) {
buffer[offset++] = (byte) (i >> 24);
buffer[offset++] = (byte) (i >> 16);
buffer[offset++] = (byte) (i >> 8);
buffer[offset++] = (byte) i;
}
public void putString(String s) {
//s.getBytes(0, s.length(), buffer, offset);
System.arraycopy(s.getBytes(), 0, buffer, offset, s.length());
offset += s.length();
buffer[offset++] = 10; // null terminate
}
public void putBytes(byte src[], int srcPos, int len) {
//for (int k = srcPos; k < srcPos + len; k++)
// buffer[offset++] = src[k];
System.arraycopy(src, srcPos, buffer, offset, len);
offset += len;
}
public int getUnsignedByte() {
return buffer[offset++] & 0xff;
}
public int getUnsignedShort() {
offset += 2;
return ((buffer[offset - 2] & 0xff) << 8) + (buffer[offset - 1] & 0xff);
}
public int getUnsignedInt() {
offset += 4;
return ((buffer[offset - 4] & 0xff) << 24) + ((buffer[offset - 3] & 0xff) << 16) + ((buffer[offset - 2] & 0xff) << 8) + (buffer[offset - 1] & 0xff);
}
public void getBytes(byte dest[], int destPos, int len) {
//for (int k = destPos; k < destPos + len; k++)
// dest[k] = buffer[offset++];
System.arraycopy(buffer, offset, dest, destPos, len);
offset += len;
}
public void encrypt(BigInteger exponent, BigInteger modulus) {
int i = offset;
offset = 0;
byte buf[] = new byte[i];
getBytes(buf, 0, i);
BigInteger biginteger2 = new BigInteger(buf);
BigInteger biginteger3 = biginteger2.modPow(exponent, modulus);
byte abyte1[] = biginteger3.toByteArray();
offset = 0;
putByte(abyte1.length);
putBytes(abyte1, 0, abyte1.length);
}
}

+ 101
- 0
mudclient204-threadless/ChatMessage.java View File

@ -0,0 +1,101 @@
public class ChatMessage {
public static byte scrambledbytes[] = new byte[100];
public static char chars[] = new char[100];
private static char charmap[] = {
' ', 'e', 't', 'a', 'o', 'i', 'h', 'n', 's', 'r',
'd', 'l', 'u', 'm', 'w', 'c', 'y', 'f', 'g', 'p',
'b', 'v', 'k', 'x', 'j', 'q', 'z', '0', '1', '2',
'3', '4', '5', '6', '7', '8', '9', ' ', '!', '?',
'.', ',', ':', ';', '(', ')', '-', '&', '*', '\\',
'\'', '@', '#', '+', '=', '\243', '$', '%', '"', '[',
']'
};
public static String descramble(byte buff[], int off, int len) {
try {
int newLen = 0;
int l = -1;
for (int idx = 0; idx < len; idx++) {
int current = buff[off++] & 0xff;
int k1 = current >> 4 & 0xf;
if (l == -1) {
if (k1 < 13)
chars[newLen++] = charmap[k1];
else
l = k1;
} else {
chars[newLen++] = charmap[((l << 4) + k1) - 195];
l = -1;
}
k1 = current & 0xf;
if (l == -1) {
if (k1 < 13)
chars[newLen++] = charmap[k1];
else
l = k1;
} else {
chars[newLen++] = charmap[((l << 4) + k1) - 195];
l = -1;
}
}
boolean flag = true;
for (int l1 = 0; l1 < newLen; l1++) {
char c = chars[l1];
if (l1 > 4 && c == '@')
chars[l1] = ' ';
if (c == '%')
chars[l1] = ' ';
if (flag && c >= 'a' && c <= 'z') {
chars[l1] += '\uFFE0';// ????? 65504
flag = false;
}
if (c == '.' || c == '!')
flag = true;
}
return new String(chars, 0, newLen);
} catch (Exception Ex) {
return ".";
}
}
public static int scramble(String s) {
if (s.length() > 80)
s = s.substring(0, 80);
s = s.toLowerCase();
int off = 0;
int lshift = -1;
for (int k = 0; k < s.length(); k++) {
char currentchar = s.charAt(k);
int foundcharmapidx = 0;
for (int n = 0; n < charmap.length; n++) {
if (currentchar != charmap[n])
continue;
foundcharmapidx = n;
break;
}
if (foundcharmapidx > 12)
foundcharmapidx += 195;
if (lshift == -1) {
if (foundcharmapidx < 13)
lshift = foundcharmapidx;
else
scrambledbytes[off++] = (byte) foundcharmapidx;
} else if (foundcharmapidx < 13) {
scrambledbytes[off++] = (byte) ((lshift << 4) + foundcharmapidx);
lshift = -1;
} else {
scrambledbytes[off++] = (byte) ((lshift << 4) + (foundcharmapidx >> 4));
lshift = foundcharmapidx & 0xf;
}
}
if (lshift != -1)
scrambledbytes[off++] = (byte) (lshift << 4);
return off;
}
}

+ 130
- 0
mudclient204-threadless/ClientStream.java View File

@ -0,0 +1,130 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class ClientStream extends Packet {
private InputStream instream;
private OutputStream outstream;
private Socket socket;
private boolean closing;
private byte buffer[];
private int endoffset;
private int offset;
private boolean closed;
public ClientStream(Socket socket, GameShell applet) throws IOException {
closing = false;
closed = true;
this.socket = socket;
instream = socket.getInputStream();
outstream = socket.getOutputStream();
closed = false;
//applet.startThread(this);
}
public void closeStream() {
super.closeStream();
closing = true;
try {
if (instream != null)
instream.close();
if (outstream != null)
outstream.close();
if (socket != null)
socket.close();
} catch (IOException Ex) {
System.out.println("Error closing stream");
}
closed = true;
//synchronized (this) {
notify();
//}
buffer = null;
}
public int readStream()
throws IOException {
if (closing)
return 0;
else
return instream.read();
}
public int availableStream()
throws IOException {
if (closing)
return 0;
else
return instream.available();
}
public void readStreamBytes(int len, int off, byte buff[])
throws IOException {
if (closing)
return;
int k = 0;
boolean flag = false;
int l;
for (; k < len; k += l)
if ((l = instream.read(buff, k + off, len - k)) <= 0)
throw new IOException("EOF");
}
public void writeStreamBytes(byte buff[], int off, int len)
throws IOException {
if (closing)
return;
if (buffer == null)
buffer = new byte[5000];
//synchronized (this) {
for (int l = 0; l < len; l++) {
buffer[offset] = buff[l + off];
offset = (offset + 1) % 5000;
if (offset == (endoffset + 4900) % 5000)
throw new IOException("buffer overflow");
}
notify();
//}
}
public void run() {
while (!closed) {
int len;
int off;
//synchronized (this) {
if (offset == endoffset)
try {
wait();
} catch (InterruptedException Ex) {
}
if (closed)
return;
off = endoffset;
if (offset >= endoffset)
len = offset - endoffset;
else
len = 5000 - endoffset;
//}
if (len > 0) {
try {
outstream.write(buffer, off, len);
} catch (IOException ioexception) {
super.socketException = true;
super.socketExceptionMessage = "Twriter:" + ioexception;
}
endoffset = (endoffset + len) % 5000;
try {
if (offset == endoffset)
outstream.flush();
} catch (IOException ioexception1) {
super.socketException = true;
super.socketExceptionMessage = "Twriter:" + ioexception1;
}
}
}
}
}

+ 133
- 0
mudclient204-threadless/Command.java View File

@ -0,0 +1,133 @@
public class Command {
public static final int CL_TRADE_CONFIRM_ACCEPT = 104;
public static final int CL_APPEARANCE = 235;
public static final int CL_BANK_CLOSE = 212;
public static final int CL_BANK_DEPOSIT = 23;
public static final int CL_BANK_WITHDRAW = 22;
public static final int CL_CAST_GROUND = 158;
public static final int CL_CAST_INVITEM = 4;
public static final int CL_CAST_NPC = 50;
public static final int CL_CAST_OBJECT = 99;
public static final int CL_CAST_PLAYER = 229;
public static final int CL_CAST_SELF = 137;
public static final int CL_CHAT = 216;
public static final int CL_CHOOSE_OPTION = 116;
public static final int CL_CLOSE_CONNECTION = 31;
public static final int CL_COMBAT_STYLE = 29;
public static final int CL_COMMAND = 38;
public static final int CL_DUEL_ACCEPT = 176;
public static final int CL_DUEL_CONFIRM_ACCEPT = 77;
public static final int CL_DUEL_DECLINE = 197;
public static final int CL_DUEL_ITEM_UPDATE = 33;
public static final int CL_DUEL_SETTINGS = 8;
public static final int CL_FRIEND_ADD = 195;
public static final int CL_FRIEND_REMOVE = 167;
public static final int CL_CAST_GROUNDITEM = 249;
public static final int CL_GROUNDITEM_TAKE = 247;
public static final int CL_IGNORE_ADD = 132;
public static final int CL_IGNORE_REMOVE = 241;
public static final int CL_INV_CMD = 90;
public static final int CL_INV_DROP = 246;
public static final int CL_INV_UNEQUIP = 170;
public static final int CL_INV_WEAR = 169;
public static final int CL_KNOWN_PLAYERS = 163;
public static final int CL_LOGIN = 0;
public static final int CL_LOGOUT = 102;
public static final int CL_NPC_ATTACK = 190;
public static final int CL_NPC_CMD = 202;
public static final int CL_NPC_TALK = 153;
public static final int CL_OBJECT_CMD1 = 136;
public static final int CL_OBJECT_CMD2 = 79;
public static final int CL_PACKET_EXCEPTION = 3;
public static final int CL_PING = 67;
public static final int CL_PLAYER_ATTACK = 171;
public static final int CL_PLAYER_DUEL = 103;
public static final int CL_PLAYER_FOLLOW = 165;
public static final int CL_PLAYER_TRADE = 142;
public static final int CL_PM = 218;
public static final int CL_PRAYER_OFF = 254;
public static final int CL_PRAYER_ON = 60;
public static final int CL_REPORT_ABUSE = 206;
public static final int CL_SESSION = 32;
public static final int CL_SETTINGS_GAME = 111;
public static final int CL_SETTINGS_PRIVACY = 64;
public static final int CL_SHOP_BUY = 236;
public static final int CL_SHOP_CLOSE = 166;
public static final int CL_SHOP_SELL = 221;
public static final int CL_SLEEP_WORD = 45;
public static final int CL_TRADE_ACCEPT = 55;
public static final int CL_TRADE_DECLINE = 230;
public static final int CL_TRADE_ITEM_UPDATE = 46;
public static final int CL_USEWITH_GROUNDITEM = 53;
public static final int CL_USEWITH_INVITEM = 91;
public static final int CL_USEWITH_NPC = 135;
public static final int CL_USEWITH_OBJECT = 115;
public static final int CL_USEWITH_PLAYER = 113;
public static final int CL_WALK = 187;
public static final int CL_WALK_ACTION = 16;
public static final int CL_WALL_OBJECT_COMMAND1 = 14;
public static final int CL_WALL_OBJECT_COMMAND2 = 127;
public static final int CL_CAST_WALLOBJECT = 180;
public static final int CL_USEWITH_WALLOBJECT = 161;
public static final int SV_APPEARANCE = 59;
public static final int SV_BANK_CLOSE = 203;
public static final int SV_BANK_OPEN = 42;
public static final int SV_BANK_UPDATE = 249;
public static final int SV_CLOSE_CONNECTION = 4;
public static final int SV_DUEL_ACCEPTED = 210;
public static final int SV_DUEL_CLOSE = 225;
public static final int SV_DUEL_CONFIRM_OPEN = 172;
public static final int SV_DUEL_OPEN = 176;
public static final int SV_DUEL_OPPONENT_ACCEPTED = 253;
public static final int SV_DUEL_SETTINGS = 30;
public static final int SV_DUEL_UPDATE = 6;
public static final int SV_FRIEND_LIST = 71;
public static final int SV_FRIEND_MESSAGE = 120;
public static final int SV_FRIEND_STATUS_CHANGE = 149;
public static final int SV_GAME_SETTINGS = 240;
public static final int SV_IGNORE_LIST = 109;
public static final int SV_INVENTORY_ITEMS = 53;
public static final int SV_INVENTORY_ITEM_REMOVE = 123;
public static final int SV_INVENTORY_ITEM_UPDATE = 90;
public static final int SV_LOGOUT_DENY = 183;
public static final int SV_MESSAGE = 131;
public static final int SV_OPTION_LIST = 245;
public static final int SV_OPTION_LIST_CLOSE = 252;
public static final int SV_PLAYER_DIED = 83;
public static final int SV_PLAYER_QUEST_LIST = 5;
public static final int SV_PLAYER_STAT_EQUIPMENT_BONUS = 153;
public static final int SV_PLAYER_STAT_EXPERIENCE_UPDATE = 33;
public static final int SV_PLAYER_STAT_FATIGUE = 114;
public static final int SV_PLAYER_STAT_FATIGUE_ASLEEP = 244;
public static final int SV_PLAYER_STAT_LIST = 156;
public static final int SV_PLAYER_STAT_UPDATE = 159;
public static final int SV_PRAYER_STATUS = 206;
public static final int SV_PRIVACY_SETTINGS = 51;
public static final int SV_REGION_ENTITY_UPDATE = 211;
public static final int SV_REGION_GROUND_ITEMS = 99;
public static final int SV_REGION_NPCS = 79;
public static final int SV_REGION_NPC_UPDATE = 104;
public static final int SV_REGION_OBJECTS = 48;
public static final int SV_REGION_PLAYERS = 191;
public static final int SV_REGION_PLAYER_UPDATE = 234;
public static final int SV_REGION_WALL_OBJECTS = 91;
public static final int SV_SERVER_MESSAGE = 89;
public static final int SV_SERVER_MESSAGE_ONTOP = 222;
public static final int SV_SHOP_CLOSE = 137;
public static final int SV_SHOP_OPEN = 101;
public static final int SV_SLEEP_CLOSE = 84;
public static final int SV_SLEEP_INCORRECT = 194;
public static final int SV_SLEEP_OPEN = 117;
public static final int SV_SOUND = 204;
public static final int SV_SYSTEM_UPDATE = 52;
public static final int SV_TELEPORT_BUBBLE = 36;
public static final int SV_TRADE_CLOSE = 128;
public static final int SV_TRADE_CONFIRM_OPEN = 20;
public static final int SV_TRADE_ITEMS = 97;
public static final int SV_TRADE_OPEN = 92;
public static final int SV_TRADE_RECIPIENT_STATUS = 162;
public static final int SV_TRADE_STATUS = 15;
public static final int SV_WELCOME = 182;
public static final int SV_WORLD_INFO = 25;
}

+ 47
- 0
mudclient204-threadless/GameCharacter.java View File

@ -0,0 +1,47 @@
final class GameCharacter {
public long hash;
public String name;
public int serverIndex;
public int serverId;
public int currentX;
public int currentY;
public int npcId;
public int stepCount;
public int animationCurrent;
public int animationNext;
public int movingStep;
public int waypointCurrent;
public int waypointsX[];
public int waypointsY[];
public int equippedItem[];
public String message;
public int messageTimeout;
public int bubbleItem;
public int bubbleTimeout;
public int damageTaken;
public int healthCurrent;
public int healthMax;
public int combatTimer;
public int level;
public int colourHair;
public int colourTop;
public int colourBottom;
public int colourSkin;
public int incomingProjectileSprite;
public int attackingPlayerServerIndex;
public int attackingNpcServerIndex;
public int projectileRange;
//public boolean unused;
//public int unused1;
public int skullVisible;
GameCharacter() {
waypointsX = new int[10];
waypointsY = new int[10];
equippedItem = new int[12];
level = -1;
//unused = false;
//unused1 = -1;
}
}

+ 544
- 0
mudclient204-threadless/GameConnection.java View File

@ -0,0 +1,544 @@
import java.io.IOException;
import java.math.BigInteger;
public class GameConnection extends GameShell {
public static int clientVersion = 1;
public static int maxReadTries;
private static BigInteger rsaExponent = new BigInteger("58778699976184461502525193738213253649000149147835990136706041084440742975821");
//private static BigInteger rsaModulus = new BigInteger("7162900525229798032761816791230527296329313291232324290237849263501208207972894053929065636522363163621000728841182238772712427862772219676577293600221789");
private static BigInteger rsaModulus = new BigInteger("7656522762491711741880224224809835569769759737077076094091609307381193032090602256314159126169417567841597729801408692196383745596665658895073411749475443");
private final int maxSocialListSize = 100;
public String server;
public int port;
public ClientStream clientStream;
public int friendListCount;
public long friendListHashes[];
public int friendListOnline[];
public int ignoreListCount;
public long ignoreList[];
public int settingsBlockChat;
public int settingsBlockPrivate;
public int settingsBlockTrade;
public int settingsBlockDuel;
public long sessionID;
public int worldFullTimeout;
public int moderatorLevel;
String username;
String password;
byte incomingPacket[];
int autoLoginTimeout;
long packetLastRead;
private int anIntArray629[];
private int anInt630;
public GameConnection() {
server = "127.0.0.1";
port = 43594;
username = "";
password = "";
incomingPacket = new byte[5000];
friendListHashes = new long[200];
friendListOnline = new int[200];
ignoreList = new long[maxSocialListSize];
anIntArray629 = new int[maxSocialListSize];
}
protected void login(String u, String p, boolean reconnecting) {
if (worldFullTimeout > 0) {
showLoginScreenStatus("Please wait...", "Connecting to server");
try {
Thread.sleep(2000L);
} catch (Exception Ex) {
}
showLoginScreenStatus("Sorry! The server is currently full.", "Please try again later");
return;
}
try {
username = u;
u = Utility.formatAuthString(u, 20);
password = p;
p = Utility.formatAuthString(p, 20);
if (u.trim().length() == 0) {
showLoginScreenStatus("You must enter both a username", "and a password - Please try again");
return;
}
if (reconnecting)
drawTextBox("Connection lost! Please wait...", "Attempting to re-establish");
else
showLoginScreenStatus("Please wait...", "Connecting to server");
clientStream = new ClientStream(createSocket(server, port), this);
clientStream.maxReadTries = maxReadTries;
long l = Utility.username2hash(u);
clientStream.newPacket((Command.CL_SESSION));
clientStream.putByte((int) (l >> 16 & 31L));
clientStream.flushPacket();
long sessid = clientStream.getLong();
sessionID = sessid;
if (sessid == 0L) {
showLoginScreenStatus("Login server offline.", "Please try again in a few mins");
return;
}
System.out.println("Verb: Session id: " + sessid);
int limit30 = 0;
/*
try {
if (getStartedAsApplet()) {
String s2 = getParameter("limit30");
if (s2.equals("1"))
limit30 = 1;
}
} catch (Exception Ex) {
}*/
int ai[] = new int[4];
ai[0] = (int) (Math.random() * 99999999D);
ai[1] = (int) (Math.random() * 99999999D);
ai[2] = (int) (sessid >> 32);
ai[3] = (int) sessid;
// TODO maybe re-enable RSA later
/*
Buffer buffer = new Buffer(new byte[500]);
buffer.offset = 0;
buffer.putByte(10);
buffer.putInt(ai[0]);
buffer.putInt(ai[1]);
buffer.putInt(ai[2]);
buffer.putInt(ai[3]);
buffer.putInt(getLinkUID());
buffer.putString(u);
buffer.putString(p);
buffer.encrypt(rsaExponent, rsaModulus);
*/
clientStream.newPacket((Command.CL_LOGIN));
if (reconnecting)
clientStream.putByte(1);
else
clientStream.putByte(0);
clientStream.putShort(clientVersion);
clientStream.putByte(limit30);
clientStream.putByte(10);
clientStream.putInt(ai[0]);
clientStream.putInt(ai[1]);
clientStream.putInt(ai[2]);
clientStream.putInt(ai[3]);
clientStream.putInt(getLinkUID());
clientStream.putString(u);
clientStream.putString(p);
//clientStream.putBytes(buffer.buffer, 0, buffer.offset);
clientStream.flushPacket();
clientStream.seedIsaac(ai);
int resp = clientStream.readStream();
System.out.println("login response:" + resp);
if (resp == 25) {
moderatorLevel = 1;
autoLoginTimeout = 0;
resetGame();
return;
}
if (resp == 0) {
moderatorLevel = 0;
autoLoginTimeout = 0;
resetGame();
return;
}
if (resp == 1) {
autoLoginTimeout = 0;
method37();
return;
}
if (reconnecting) {
u = "";
p = "";
resetLoginVars();
return;
}
if (resp == -1) {
showLoginScreenStatus("Error unable to login.", "Server timed out");
return;
}
if (resp == 3) {
showLoginScreenStatus("Invalid username or password.", "Try again, or create a new account");
return;
}
if (resp == 4) {
showLoginScreenStatus("That username is already logged in.", "Wait 60 seconds then retry");
return;
}
if (resp == 5) {
showLoginScreenStatus("The client has been updated.", "Please reload this page");
return;
}
if (resp == 6) {
showLoginScreenStatus("You may only use 1 character at once.", "Your ip-address is already in use");
return;
}
if (resp == 7) {
showLoginScreenStatus("Login attempts exceeded!", "Please try again in 5 minutes");
return;
}
if (resp == 8) {
showLoginScreenStatus("Error unable to login.", "Server rejected session");
return;
}
if (resp == 9) {
showLoginScreenStatus("Error unable to login.", "Loginserver rejected session");
return;
}
if (resp == 10) {
showLoginScreenStatus("That username is already in use.", "Wait 60 seconds then retry");
return;
}
if (resp == 11) {
showLoginScreenStatus("Account temporarily disabled.", "Check your message inbox for details");
return;
}
if (resp == 12) {
showLoginScreenStatus("Account permanently disabled.", "Check your message inbox for details");
return;
}
if (resp == 14) {
showLoginScreenStatus("Sorry! This world is currently full.", "Please try a different world");
worldFullTimeout = 1500;
return;
}
if (resp == 15) {
showLoginScreenStatus("You need a members account", "to login to this world");
return;
}
if (resp == 16) {
showLoginScreenStatus("Error - no reply from loginserver.", "Please try again");
return;
}
if (resp == 17) {
showLoginScreenStatus("Error - failed to decode profile.", "Contact customer support");
return;
}
if (resp == 18) {
showLoginScreenStatus("Account suspected stolen.", "Press 'recover a locked account' on front page.");
return;
}
if (resp == 20) {
showLoginScreenStatus("Error - loginserver mismatch", "Please try a different world");
return;
}
if (resp == 21) {
showLoginScreenStatus("Unable to login.", "That is not an RS-Classic account");
return;
}
if (resp == 22) {
showLoginScreenStatus("Password suspected stolen.", "Press 'change your password' on front page.");
return;
} else {
showLoginScreenStatus("Error unable to login.", "Unrecognised response code");
return;
}
} catch (Exception exception) {
System.out.println(String.valueOf(exception));
}
if (autoLoginTimeout > 0) {
try {
Thread.sleep(5000L);
} catch (Exception Ex) {
}
autoLoginTimeout--;
login(username, password, reconnecting);
}
if (reconnecting) {
username = "";
password = "";
resetLoginVars();
} else {
showLoginScreenStatus("Sorry! Unable to connect.", "Check internet settings or try another world");
}
}
protected void closeConnection() {
if (clientStream != null)
try {
clientStream.newPacket((Command.CL_CLOSE_CONNECTION));
clientStream.flushPacket();
} catch (IOException Ex) {
}
username = "";
password = "";
resetLoginVars();
}
protected void lostConnection() {
try {
throw new Exception("");
} catch (Exception ex) {
System.out.println("loast connection: ");
ex.printStackTrace();
}
System.out.println("Lost connection");
autoLoginTimeout = 10;
login(username, password, true);
}
protected void drawTextBox(String s, String s1) {
/*Graphics g = getGraphics();
Font font = new Font("Helvetica", 1, 15);
char c = '\u0200';
char c1 = '\u0158';
g.setColor(Color.black);
g.fillRect(c / 2 - 140, c1 / 2 - 25, 280, 50);
g.setColor(Color.white);
g.drawRect(c / 2 - 140, c1 / 2 - 25, 280, 50);
drawString(g, s, font, c / 2, c1 / 2 - 10);
drawString(g, s1, font, c / 2, c1 / 2 + 10);*/
}
protected void checkConnection() {
long l = System.currentTimeMillis();
if (clientStream.hasPacket())
packetLastRead = l;
if (l - packetLastRead > 5000L) {
packetLastRead = l;
clientStream.newPacket((Command.CL_PING));
clientStream.sendPacket();
}
try {
clientStream.writePacket(20);
} catch (IOException Ex) {
lostConnection();
return;
}
if (!method43())
return;
int psize = clientStream.readPacket(incomingPacket);
if (psize > 0) {
int ptype = clientStream.isaacCommand(incomingPacket[0] & 0xff);
handlePacket(ptype, ptype, psize);
}
}
private void handlePacket(int opcode, int ptype, int psize) {
//ptype = clientStream.isaacCommand(ptype);
//System.out.println(String.format("opcode:%s(%d) psize:%d", opcode.name(), ptype, psize));
System.out.println("opcode:" + opcode + " psize:" + psize);
if (opcode == Command.SV_MESSAGE) {
String s = new String(incomingPacket, 1, psize - 1);
showServerMessage(s);
}
if (opcode == Command.SV_CLOSE_CONNECTION)
closeConnection();
if (opcode == Command.SV_LOGOUT_DENY) {
cantLogout();
return;
}
if (opcode == Command.SV_FRIEND_LIST) {
friendListCount = Utility.getUnsignedByte(incomingPacket[1]);
for (int k = 0; k < friendListCount; k++) {
friendListHashes[k] = Utility.getUnsignedLong(incomingPacket, 2 + k * 9);
friendListOnline[k] = Utility.getUnsignedByte(incomingPacket[10 + k * 9]);
}
sortFriendsList();
return;
}
if (opcode == Command.SV_FRIEND_STATUS_CHANGE) {
long hash = Utility.getUnsignedLong(incomingPacket, 1);
int online = incomingPacket[9] & 0xff;
for (int i2 = 0; i2 < friendListCount; i2++)
if (friendListHashes[i2] == hash) {
if (friendListOnline[i2] == 0 && online != 0)
showServerMessage("@pri@" + Utility.hash2username(hash) + " has logged in");
if (friendListOnline[i2] != 0 && online == 0)
showServerMessage("@pri@" + Utility.hash2username(hash) + " has logged out");
friendListOnline[i2] = online;
psize = 0; // not sure what this is for
sortFriendsList();
return;
}
friendListHashes[friendListCount] = hash;
friendListOnline[friendListCount] = online;
friendListCount++;
sortFriendsList();
return;
}
if (opcode == Command.SV_IGNORE_LIST) {
ignoreListCount = Utility.getUnsignedByte(incomingPacket[1]);
for (int i1 = 0; i1 < ignoreListCount; i1++)
ignoreList[i1] = Utility.getUnsignedLong(incomingPacket, 2 + i1 * 8);
return;
}
if (opcode == Command.SV_PRIVACY_SETTINGS) {
settingsBlockChat = incomingPacket[1];
settingsBlockPrivate = incomingPacket[2];
settingsBlockTrade = incomingPacket[3];
settingsBlockDuel = incomingPacket[4];
return;
}
if (opcode == Command.SV_FRIEND_MESSAGE) {
long from = Utility.getUnsignedLong(incomingPacket, 1);
int k1 = Utility.getUnsignedInt(incomingPacket, 9); // is this some sort of message id ?
for (int j2 = 0; j2 < maxSocialListSize; j2++)
if (anIntArray629[j2] == k1)
return;
anIntArray629[anInt630] = k1;
anInt630 = (anInt630 + 1) % maxSocialListSize;
String msg = WordFilter.filter(ChatMessage.descramble(incomingPacket, 13, psize - 13));
showServerMessage("@pri@" + Utility.hash2username(from) + ": tells you " + msg);
return;
} else {
handleIncomingPacket(opcode, ptype, psize, incomingPacket);
return;
}
}
private void sortFriendsList() {
boolean flag = true;
while (flag) {
flag = false;
for (int i = 0; i < friendListCount - 1; i++)
if (friendListOnline[i] != 255 && friendListOnline[i + 1] == 255 || friendListOnline[i] == 0 && friendListOnline[i + 1] != 0) {
int j = friendListOnline[i];
friendListOnline[i] = friendListOnline[i + 1];
friendListOnline[i + 1] = j;
long l = friendListHashes[i];
friendListHashes[i] = friendListHashes[i + 1];
friendListHashes[i + 1] = l;
flag = true;
}
}
}
protected void sendPrivacySettings(int chat, int priv, int trade, int duel) {
clientStream.newPacket((Command.CL_SETTINGS_PRIVACY));
clientStream.putByte(chat);
clientStream.putByte(priv);
clientStream.putByte(trade);
clientStream.putByte(duel);
clientStream.sendPacket();
}
protected void ignoreAdd(String s) {
long l = Utility.username2hash(s);
clientStream.newPacket((Command.CL_IGNORE_ADD));
clientStream.putLong(l);
clientStream.sendPacket();
for (int i = 0; i < ignoreListCount; i++)
if (ignoreList[i] == l)
return;
if (ignoreListCount >= maxSocialListSize) {
return;
} else {
ignoreList[ignoreListCount++] = l;
return;
}
}
protected void ignoreRemove(long l) {
clientStream.newPacket((Command.CL_IGNORE_REMOVE));
clientStream.putLong(l);
clientStream.sendPacket();
for (int i = 0; i < ignoreListCount; i++)
if (ignoreList[i] == l) {
ignoreListCount--;
for (int j = i; j < ignoreListCount; j++)
ignoreList[j] = ignoreList[j + 1];
return;
}
}
protected void friendAdd(String s) {
clientStream.newPacket((Command.CL_FRIEND_ADD));
clientStream.putLong(Utility.username2hash(s));
clientStream.sendPacket();
long l = Utility.username2hash(s);
for (int i = 0; i < friendListCount; i++)
if (friendListHashes[i] == l)
return;
if (friendListCount >= maxSocialListSize) {
return;
} else {
friendListHashes[friendListCount] = l;
friendListOnline[friendListCount] = 0;
friendListCount++;