22 package com.realtime.crossfire.jxclient.server.crossfire;
40 import java.io.BufferedReader;
41 import java.io.ByteArrayInputStream;
42 import java.io.IOException;
43 import java.io.InputStreamReader;
44 import java.io.UnsupportedEncodingException;
45 import java.nio.BufferUnderflowException;
46 import java.nio.ByteBuffer;
47 import java.nio.ByteOrder;
48 import java.util.ArrayList;
49 import java.util.Arrays;
50 import java.util.LinkedHashMap;
51 import java.util.List;
53 import java.util.regex.Pattern;
54 import org.jetbrains.annotations.NotNull;
55 import org.jetbrains.annotations.Nullable;
77 private static final Pattern
PATTERN_DOT = Pattern.compile(
":");
83 private static final Pattern
PATTERN_BAR = Pattern.compile(
"\\|+");
208 private final ByteBuffer
byteBuffer = ByteBuffer.wrap(writeBuffer);
590 @SuppressWarnings(
"FieldCanBeLocal")
594 public void connecting() {
609 public void packetSent(@NotNull
final byte[] buf,
final int len) {
614 public void disconnecting(@NotNull
final String reason,
final boolean isError) {
619 public void disconnected(@NotNull
final String reason) {
639 byteBuffer.order(ByteOrder.BIG_ENDIAN);
651 if (listener != null && crossfireUpdateMapListener != null) {
652 throw new IllegalStateException(
"listener already set to "+crossfireUpdateMapListener.getClass().getName());
654 crossfireUpdateMapListener = listener;
662 defaultServerConnection.
start();
669 public void stop() throws InterruptedException {
670 defaultServerConnection.
stop();
678 pendingMapHeight = 0;
698 switch (packet.get()) {
700 switch (packet.get()) {
703 if (packet.get() !=
'c') {
706 if (packet.get() !=
'o') {
709 if (packet.get() !=
'u') {
712 if (packet.get() !=
'n') {
715 if (packet.get() !=
't') {
718 if (packet.get() !=
'p') {
721 if (packet.get() !=
'l') {
724 if (packet.get() !=
'a') {
727 if (packet.get() !=
'y') {
730 if (packet.get() !=
'e') {
733 if (packet.get() !=
'r') {
736 if (packet.get() !=
's') {
739 if (packet.get() !=
' ') {
742 if (debugProtocol != null) {
749 if (packet.get() !=
'd') {
752 switch (packet.get()) {
754 if (packet.get() !=
'n') {
757 if (packet.get() !=
'o') {
760 if (packet.get() !=
'w') {
763 if (packet.get() !=
'l') {
766 if (packet.get() !=
'e') {
769 if (packet.get() !=
'd') {
772 if (packet.get() !=
'g') {
775 if (packet.get() !=
'e') {
778 if (packet.get() !=
' ') {
786 if (packet.get() !=
'e') {
789 if (packet.get() !=
'_') {
792 switch (packet.get()) {
794 if (packet.get() !=
'a') {
797 if (packet.get() !=
'i') {
800 if (packet.get() !=
'l') {
803 if (packet.get() !=
'e') {
806 if (packet.get() !=
'd') {
809 if (packet.hasRemaining()) {
812 if (debugProtocol != null) {
819 if (packet.get() !=
'u') {
822 if (packet.get() !=
'c') {
825 if (packet.get() !=
'c') {
828 if (packet.get() !=
'e') {
831 if (packet.get() !=
's') {
834 if (packet.get() !=
's') {
837 if (packet.hasRemaining()) {
840 if (debugProtocol != null) {
849 if (packet.get() !=
'u') {
852 if (packet.get() !=
'e') {
855 if (packet.get() !=
's') {
858 if (packet.get() !=
't') {
861 if (packet.get() !=
' ') {
869 if (packet.get() !=
'p') {
872 if (packet.get() !=
'e') {
875 if (packet.get() !=
'l') {
878 if (packet.get() !=
'l') {
881 if (packet.get() !=
' ') {
890 if (packet.get() !=
'i') {
893 if (packet.get() !=
'm') {
896 if (packet.get() !=
' ') {
905 if (packet.get() !=
'o') {
908 if (packet.get() !=
'm') {
911 if (packet.get() !=
'c') {
914 if (packet.get() !=
' ') {
921 switch (packet.get()) {
923 if (packet.get() !=
'l') {
926 switch (packet.get()) {
928 switch (packet.get()) {
930 if (packet.get() !=
'v') {
933 if (packet.get() !=
' ') {
940 if (packet.get() !=
'e') {
943 if (packet.get() !=
'm') {
946 if (packet.get() !=
' ') {
955 if (packet.get() !=
'p') {
958 if (packet.get() !=
'e') {
961 if (packet.get() !=
'l') {
964 if (packet.get() !=
'l') {
967 if (packet.get() !=
' ') {
976 if (packet.get() !=
'a') {
979 if (packet.get() !=
'w') {
982 switch (packet.get()) {
984 if (packet.get() !=
'x') {
987 if (packet.get() !=
't') {
990 if (packet.get() !=
'i') {
993 if (packet.get() !=
'n') {
996 if (packet.get() !=
'f') {
999 if (packet.get() !=
'o') {
1002 if (packet.get() !=
' ') {
1009 if (packet.get() !=
'n') {
1012 if (packet.get() !=
'f') {
1015 if (packet.get() !=
'o') {
1018 if (packet.get() !=
' ') {
1029 if (packet.get() !=
'x') {
1032 if (packet.get() !=
't') {
1035 if (packet.get() !=
'e') {
1038 if (packet.get() !=
'n') {
1041 if (packet.get() !=
'd') {
1044 if (packet.get() !=
'e') {
1047 if (packet.get() !=
'd') {
1050 switch (packet.get()) {
1052 if (packet.get() !=
'n') {
1055 if (packet.get() !=
'f') {
1058 if (packet.get() !=
'o') {
1061 if (packet.get() !=
'S') {
1064 if (packet.get() !=
'e') {
1067 if (packet.get() !=
't') {
1070 if (packet.get() !=
' ') {
1077 if (packet.get() !=
'e') {
1080 if (packet.get() !=
'x') {
1083 if (packet.get() !=
't') {
1086 if (packet.get() !=
'S') {
1089 if (packet.get() !=
'e') {
1092 if (packet.get() !=
't') {
1095 if (packet.get() !=
' ') {
1104 if (packet.get() !=
'a') {
1107 switch (packet.get()) {
1109 if (packet.get() !=
'e') {
1112 if (packet.get() !=
'2') {
1115 if (packet.get() !=
' ') {
1122 if (packet.get() !=
'l') {
1125 if (packet.get() !=
'u') {
1128 if (packet.get() !=
'r') {
1131 if (packet.get() !=
'e') {
1134 if (packet.get() !=
' ') {
1143 if (packet.get() !=
'o') {
1146 if (packet.get() !=
'o') {
1149 if (packet.get() !=
'd') {
1152 if (packet.get() !=
'b') {
1155 if (packet.get() !=
'y') {
1158 if (packet.get() !=
'e') {
1161 if (packet.get() !=
' ') {
1168 switch (packet.get()) {
1170 if (packet.get() !=
'a') {
1173 if (packet.get() !=
'g') {
1176 if (packet.get() !=
'e') {
1179 if (packet.get() !=
'2') {
1182 if (packet.get() !=
' ') {
1189 if (packet.get() !=
'e') {
1192 if (packet.get() !=
'm') {
1195 if (packet.get() !=
'2') {
1198 if (packet.get() !=
' ') {
1207 switch (packet.get()) {
1209 switch (packet.get()) {
1211 if (packet.get() !=
'i') {
1214 if (packet.get() !=
'c') {
1217 if (packet.get() !=
'm') {
1220 if (packet.get() !=
'a') {
1223 if (packet.get() !=
'p') {
1226 if (packet.get() !=
' ') {
1233 switch (packet.get()) {
1235 if (packet.get() !=
' ') {
1242 if (packet.get() !=
'x') {
1245 if (packet.get() !=
't') {
1248 if (packet.get() !=
'e') {
1251 if (packet.get() !=
'n') {
1254 if (packet.get() !=
'd') {
1257 if (packet.get() !=
'e') {
1260 if (packet.get() !=
'd') {
1263 if (packet.get() !=
' ') {
1274 if (packet.get() !=
's') {
1277 if (packet.get() !=
'i') {
1280 if (packet.get() !=
'c') {
1283 if (packet.get() !=
' ') {
1292 if (packet.get() !=
'e') {
1295 if (packet.get() !=
'w') {
1298 if (packet.get() !=
'm') {
1301 if (packet.get() !=
'a') {
1304 if (packet.get() !=
'p') {
1311 switch (packet.get()) {
1313 if (packet.get() !=
'c') {
1316 if (packet.get() !=
'k') {
1319 if (packet.get() !=
'u') {
1322 if (packet.get() !=
'p') {
1325 if (packet.get() !=
' ') {
1332 if (packet.get() !=
'a') {
1335 if (packet.get() !=
'y') {
1338 if (packet.get() !=
'e') {
1341 if (packet.get() !=
'r') {
1344 if (packet.get() !=
' ') {
1353 if (packet.get() !=
'u') {
1356 if (packet.get() !=
'e') {
1359 if (packet.get() !=
'r') {
1362 if (packet.get() !=
'y') {
1365 if (packet.get() !=
' ') {
1372 if (packet.get() !=
'e') {
1375 if (packet.get() !=
'p') {
1378 if (packet.get() !=
'l') {
1381 if (packet.get() !=
'y') {
1384 if (packet.get() !=
'i') {
1387 if (packet.get() !=
'n') {
1390 if (packet.get() !=
'f') {
1393 if (packet.get() !=
'o') {
1396 if (packet.get() !=
' ') {
1403 switch (packet.get()) {
1405 if (packet.get() !=
't') {
1408 if (packet.get() !=
'u') {
1411 if (packet.get() !=
'p') {
1414 if (packet.get() !=
' ') {
1421 if (packet.get() !=
'o') {
1424 if (packet.get() !=
'o') {
1427 if (packet.get() !=
't') {
1430 if (packet.get() !=
'h') {
1433 if (packet.get() !=
' ') {
1440 if (packet.get() !=
'u') {
1443 if (packet.get() !=
'n') {
1446 if (packet.get() !=
'd') {
1449 switch (packet.get()) {
1455 if (packet.get() !=
' ') {
1464 if (packet.get() !=
'a') {
1467 if (packet.get() !=
't') {
1470 if (packet.get() !=
's') {
1473 if (packet.get() !=
' ') {
1482 if (packet.get() !=
'i') {
1485 if (packet.get() !=
'c') {
1488 if (packet.get() !=
'k') {
1491 if (packet.get() !=
' ') {
1498 if (packet.get() !=
'p') {
1501 if (packet.get() !=
'd') {
1504 switch (packet.get()) {
1506 if (packet.get() !=
't') {
1509 if (packet.get() !=
'e') {
1512 if (packet.get() !=
'm') {
1515 if (packet.get() !=
' ') {
1522 if (packet.get() !=
'u') {
1525 if (packet.get() !=
'e') {
1528 if (packet.get() !=
's') {
1531 if (packet.get() !=
't') {
1534 if (packet.get() !=
' ') {
1541 if (packet.get() !=
'p') {
1544 if (packet.get() !=
'e') {
1547 if (packet.get() !=
'l') {
1550 if (packet.get() !=
'l') {
1553 if (packet.get() !=
' ') {
1562 if (packet.get() !=
'e') {
1565 if (packet.get() !=
'r') {
1568 if (packet.get() !=
's') {
1571 if (packet.get() !=
'i') {
1574 if (packet.get() !=
'o') {
1577 if (packet.get() !=
'n') {
1580 if (packet.get() !=
' ') {
1586 }
catch (
final IllegalArgumentException ex) {
1587 if (debugProtocol != null) {
1590 }
catch (
final BufferUnderflowException ex) {
1591 if (debugProtocol != null) {
1594 }
catch (
final ArrayIndexOutOfBoundsException ex) {
1595 if (debugProtocol != null) {
1598 }
catch (
final StringIndexOutOfBoundsException ex) {
1599 if (debugProtocol != null) {
1600 debugProtocol.
debugProtocolWrite(
"StringIndexOutOfBoundsException while command parsing: "+ex+
"\n"+
hexDump(packet), ex);
1603 if (debugProtocol != null) {
1611 if (debugProtocol != null) {
1626 final int lenType =
getInt1(packet);
1627 if (lenType == 0xFF) {
1631 final int len = (lenType>>5)&7;
1632 final int type = lenType&31;
1670 if (debugProtocol != null) {
1688 final int darkness =
getInt1(packet);
1689 if (debugProtocol != null) {
1709 final int face =
getInt2(packet);
1711 if (debugProtocol != null) {
1716 if (debugProtocol != null) {
1723 }
else if (len == 4) {
1725 }
else if (len != 2) {
1726 if (debugProtocol != null) {
1747 final int smooth =
getInt1(packet);
1748 if (debugProtocol != null) {
1753 final int animSpeed =
getInt1(packet);
1754 if (debugProtocol != null) {
1774 final int animSpeed =
getInt1(packet);
1775 if (debugProtocol != null) {
1780 final int smooth =
getInt1(packet);
1781 if (debugProtocol != null) {
1793 if (debugProtocol != null) {
1798 if (debugProtocol != null) {
1799 debugProtocol.
debugProtocolWrite(
"negotiateMapSize: clientSocketState="+clientSocketState+
", ignoring");
1803 if (pendingMapWidth != 0 || pendingMapHeight != 0) {
1804 if (debugProtocol != null) {
1809 if (currentMapWidth == mapWidth && currentMapHeight == mapHeight) {
1810 if (debugProtocol != null) {
1811 debugProtocol.
debugProtocolWrite(
"negotiateMapSize: same as current map size, ignoring");
1815 pendingMapWidth = mapWidth;
1816 pendingMapHeight = mapHeight;
1817 sendSetup(
"mapsize "+pendingMapWidth+
"x"+pendingMapHeight);
1829 if (sendingRequestInfo != null && sendingRequestInfo.equals(infoType)) {
1830 sendingRequestInfo = null;
1848 case "knowledge_info":
1877 System.err.println(
"Ignoring unexpected replyinfo type '"+infoType+
"'.");
1888 final byte[] data =
new byte[packet.remaining()];
1890 try (
final ByteArrayInputStream is =
new ByteArrayInputStream(data)) {
1891 try (
final InputStreamReader isr =
new InputStreamReader(is)) {
1892 try (
final BufferedReader d =
new BufferedReader(isr)) {
1893 final String info = d.readLine();
1895 throw new IOException(
"Truncated parameter in image_info");
1898 final int nrPics = Integer.parseInt(info);
1912 final byte[] data =
new byte[packet.remaining()];
1914 try (
final ByteArrayInputStream is =
new ByteArrayInputStream(data)) {
1915 try (
final InputStreamReader isr =
new InputStreamReader(is)) {
1916 try (
final BufferedReader d =
new BufferedReader(isr)) {
1918 final CharSequence r = d.readLine();
1923 final String[] sk = PATTERN_DOT.split(r, 3);
1924 if (sk.length < 2 || sk.length > 3) {
1925 System.err.println(
"Ignoring skill definition for invalid skill: "+r+
".");
1931 skillId = Integer.parseInt(sk[0]);
1932 }
catch (
final NumberFormatException ignored) {
1933 System.err.println(
"Ignoring skill definition for invalid skill: "+r+
".");
1938 System.err.println(
"Ignoring skill definition for invalid skill id "+skillId+
": "+r+
".");
1943 if (sk.length > 2) {
1945 face = Integer.parseInt(sk[2]);
1946 }
catch (
final NumberFormatException ignored) {
1947 System.err.println(
"Ignoring skill definition for invalid face: "+r+
".");
1963 final int numLevels =
getInt2(packet);
1964 final long[] expTable =
new long[numLevels];
1965 for (
int level = 1; level < numLevels; level++) {
1966 expTable[level] =
getInt8(packet);
1968 if (packet.hasRemaining()) {
1969 System.err.println(
"Ignoring excess data at end of exp_table");
1974 if (loginMethod == 0) {
1990 final byte[] data =
new byte[packet.remaining()];
1992 try (
final ByteArrayInputStream is =
new ByteArrayInputStream(data)) {
1993 try (
final InputStreamReader isr =
new InputStreamReader(is)) {
1994 try (
final BufferedReader d =
new BufferedReader(isr)) {
1996 final CharSequence r = d.readLine();
2001 final String[] sk = PATTERN_DOT.split(r);
2002 if (sk.length != 4) {
2003 System.err.println(
"Ignoring knowledge definition for invalid knowledge: "+r+
".");
2009 face = Integer.parseInt(sk[2]);
2010 }
catch (
final NumberFormatException ignored) {
2011 System.err.println(
"Ignoring knowledge definition for invalid face: "+r+
".");
2028 while (packet.hasRemaining()) {
2029 final int type =
getInt1(packet);
2030 final int length =
getInt2(packet);
2033 final byte[] archName =
new byte[length];
2034 packet.get(archName);
2047 System.err.println(
"Ignoring startingmap type "+type);
2059 while (packet.remaining() > 0 && packet.get(packet.position()) ==
'|') {
2062 final CharSequence raceList =
getString(packet, packet.remaining());
2063 final String[] races = PATTERN_BAR.split(raceList);
2066 for (
final String race : races) {
2076 while (packet.remaining() > 0 && packet.get(packet.position()) ==
'|') {
2079 final CharSequence classList =
getString(packet, packet.remaining());
2080 final String[] classes = PATTERN_BAR.split(classList);
2083 for (
final String class_ : classes) {
2098 while (packet.hasRemaining()) {
2118 System.err.println(
"Ignoring race_info type "+type);
2123 if (debugProtocol != null) {
2124 debugProtocol.
debugProtocolWrite(
"recv replyinfo "+(raceInfo ?
"race_info" :
"class_info")+
" "+classRaceInfo);
2140 while (packet.hasRemaining()) {
2141 final int len =
getInt1(packet)-1;
2142 final String line =
getString(packet, len);
2145 final String[] tokens = PATTERN_SPACE.split(line, 3);
2146 if (tokens.length != 3) {
2149 final String typeString = tokens[0];
2150 final String variableName = tokens[1];
2151 final String values = tokens[2];
2152 switch (typeString) {
2174 if (debugProtocol != null) {
2189 if (variableName.equals(
"race")) {
2190 if (!values.equals(
"requestinfo")) {
2193 newCharInfoBuilder.setRaceChoice();
2194 }
else if (variableName.equals(
"class")) {
2195 if (!values.equals(
"requestinfo")) {
2198 newCharInfoBuilder.setClassChoice();
2199 }
else if (variableName.equals(
"startingmap")) {
2200 if (!values.equals(
"requestinfo")) {
2203 newCharInfoBuilder.setStartingMapChoice();
2204 }
else if (!required) {
2205 System.err.println(
"unknown variable name '"+variableName+
"' in replyinfo newcharinfo");
2219 switch (variableName) {
2223 points = Integer.parseInt(values);
2224 }
catch (
final NumberFormatException ignored) {
2225 throw new UnknownCommandException(
"'"+variableName+
"' variable in replyinfo newcharinfo has invalid value '"+values+
"'.");
2227 newCharInfoBuilder.setPoints(points);
2231 final String[] tmp = PATTERN_SPACE.split(values, 2);
2232 if (tmp.length != 2) {
2233 throw new UnknownCommandException(
"'"+variableName+
"' variable in replyinfo newcharinfo has invalid value '"+values+
"'.");
2238 minValue = Integer.parseInt(tmp[0]);
2239 maxValue = Integer.parseInt(tmp[1]);
2240 }
catch (
final NumberFormatException ignored) {
2241 throw new UnknownCommandException(
"'"+variableName+
"' variable in replyinfo newcharinfo has invalid value '"+values+
"'.");
2243 newCharInfoBuilder.setStatRange(minValue, maxValue);
2247 newCharInfoBuilder.setStatNames(PATTERN_SPACE.split(values));
2261 System.err.println(
"ignoring informational "+variableName+
"="+values+
" in replyinfo newcharinfo");
2272 while (packet.hasRemaining()) {
2273 final int statNo =
getInt1(packet);
2321 final short int2Param = (short)
getInt2(packet);
2322 rb.setStatAdjustment(statNo, int2Param);
2332 final int int4Param =
getInt4(packet);
2333 rb.setStatAdjustment(statNo, int4Param);
2337 final long int8Param =
getInt8(packet);
2338 rb.setStatAdjustment(statNo, int8Param);
2343 final int length =
getInt1(packet);
2344 final String strParam =
getString(packet, length);
2345 System.err.println(
"replyinfo race/class_info: string stat "+statNo+
" not implemented");
2350 final short int2Param2 = (short)
getInt2(packet);
2351 rb.setStatAdjustment(statNo, int2Param2);
2353 final int level =
getInt1(packet);
2354 final long experience =
getInt8(packet);
2355 System.err.println(
"replyinfo race/class_info: skill stat "+statNo+
" not implemented");
2377 final Map<String, String> choices =
new LinkedHashMap<>();
2378 choices.put(archName, archDesc);
2380 final int archNameLength =
getInt1(packet);
2381 if (archNameLength == 0) {
2384 final String archName2 =
getString(packet, archNameLength);
2386 choices.put(archName2, archDesc2);
2388 rb.addChoice(
new Choice(choiceName, choiceDescription, choices));
2397 final int args = packet.position();
2399 if (accountName == null) {
2405 final int total =
getInt1(packet);
2407 for (
int count = 0; count < total; count++) {
2409 if (debugProtocol != null) {
2410 debugProtocol.
debugProtocolWrite(
"recv accountplayers entry: "+characterInformation);
2414 if (packet.hasRemaining()) {
2434 if (!packet.hasRemaining()) {
2438 final int len =
getInt1(packet);
2443 final int type =
getInt1(packet);
2446 accountPlayerBuilder.setName(
getString(packet, len-1));
2450 accountPlayerBuilder.setClass(
getString(packet, len-1));
2454 accountPlayerBuilder.setRace(
getString(packet, len-1));
2458 accountPlayerBuilder.setLevel(
getInt2(packet));
2462 accountPlayerBuilder.setFace(
getString(packet, len-1));
2466 accountPlayerBuilder.setParty(
getString(packet, len-1));
2470 accountPlayerBuilder.setMap(
getString(packet, len-1));
2474 accountPlayerBuilder.setFaceNumber(
getInt2(packet));
2479 if (debugProtocol != null) {
2482 packet.position(packet.position()+len-1);
2487 return accountPlayerBuilder.finish();
2495 final int args = packet.position();
2505 final int args = packet.position();
2526 final int args = packet.position();
2527 while (packet.hasRemaining()) {
2528 final int code =
getInt4(packet);
2529 final int titleLength =
getInt2(packet);
2530 final String title =
getString(packet, titleLength);
2531 final int face =
getInt4(packet);
2532 final int replay =
getInt1(packet);
2533 final int parent =
getInt4(packet);
2534 final int end =
getInt1(packet);
2535 final int stepLength =
getInt2(packet);
2536 final String step = stepLength > 0 ?
getString(packet, stepLength) :
"";
2538 if (debugProtocol != null) {
2539 debugProtocol.
debugProtocolWrite(
"recv addquest code="+code+
" title="+title+
" face="+face+
"replay="+replay+
" end="+end+
" desc="+step);
2551 final int args = packet.position();
2552 while (packet.hasRemaining()) {
2553 final int code =
getInt4(packet);
2554 final int typeLength =
getInt2(packet);
2555 final String type =
getString(packet, typeLength);
2556 final int titleLength =
getInt2(packet);
2557 final String title =
getString(packet, titleLength);
2558 final int face =
getInt4(packet);
2560 if (debugProtocol != null) {
2561 debugProtocol.
debugProtocolWrite(
"recv addknowledge code="+code+
"type="+type+
"title="+title+
" face="+face);
2573 final int args = packet.position();
2574 while (packet.hasRemaining()) {
2575 final int tag =
getInt4(packet);
2576 final int level =
getInt2(packet);
2577 final int castingTime =
getInt2(packet);
2578 final int mana =
getInt2(packet);
2579 final int grace =
getInt2(packet);
2580 final int damage =
getInt2(packet);
2581 final int skill =
getInt1(packet);
2582 final int path =
getInt4(packet);
2583 final int face =
getInt4(packet);
2584 final int nameLength =
getInt1(packet);
2585 final String name =
getString(packet, nameLength);
2586 final int messageLength =
getInt2(packet);
2587 final String message =
getString(packet, messageLength);
2588 if (debugProtocol != null) {
2589 debugProtocol.
debugProtocolWrite(
"recv addspell tag="+tag+
" lvl="+level+
" time="+castingTime+
" sp="+mana+
" gr="+grace+
" dam="+damage+
" skill="+skill+
" path="+path+
" face="+face+
" name="+name+
" msg="+message);
2591 model.
getSpellsManager().
addSpell(tag, level, castingTime, mana, grace, damage, skill, path, face, name, message);
2602 final int args = packet.position();
2603 final int num =
getInt2(packet);
2604 final int flags =
getInt2(packet);
2605 final int[] faces =
new int[packet.remaining()/2];
2606 if (faces.length <= 0) {
2609 for (
int i = 0; i < faces.length; i++) {
2612 if (packet.hasRemaining()) {
2615 if (debugProtocol != null) {
2616 debugProtocol.
debugProtocolWrite(
"recv anim num="+num+
" flags="+flags+
" faces="+Arrays.toString(faces));
2618 if ((num&~0x1FFF) != 0) {
2631 final int args = packet.position();
2632 final int packetNo =
getInt2(packet);
2633 final int time =
getInt4(packet);
2634 if (packet.hasRemaining()) {
2637 if (debugProtocol != null) {
2650 final int args = packet.position();
2654 }
while (packet.hasRemaining());
2655 if (packet.hasRemaining()) {
2658 if (debugProtocol != null) {
2671 final int args = packet.position();
2672 final int[] tags =
new int[packet.remaining()/4];
2673 for (
int i = 0; i < tags.length; i++) {
2676 if (packet.hasRemaining()) {
2679 if (debugProtocol != null) {
2692 final int args = packet.position();
2693 final int tag =
getInt4(packet);
2694 if (packet.hasRemaining()) {
2697 if (debugProtocol != null) {
2710 final int args = packet.position();
2714 }
while (packet.get(packet.position()) !=
' ');
2720 }
while (packet.get(packet.position()) !=
' ');
2725 subtype = subtype*10+
parseDigit(packet.get());
2726 }
while (packet.get(packet.position()) !=
' ');
2729 final String message =
getString(packet, packet.remaining());
2731 if (debugProtocol != null) {
2732 debugProtocol.
debugProtocolWrite(
"recv drawextinfo color="+color+
" type="+type+
"/"+subtype+
" msg="+message);
2745 final int args = packet.position();
2749 }
while (packet.get(packet.position()) !=
' ');
2752 final String message =
getString(packet, packet.remaining());
2754 if (debugProtocol != null) {
2767 final int args = packet.position();
2769 final int startPos = packet.position();
2770 while (packet.hasRemaining() && packet.get(packet.position()) !=
' ') {
2773 final String
string =
newString(packet, startPos, packet.position()-startPos);
2775 if (debugProtocol != null) {
2779 }
while (packet.hasRemaining());
2788 final int args = packet.position();
2790 final int startPos = packet.position();
2791 while (packet.hasRemaining() && packet.get(packet.position()) !=
' ') {
2794 final String type =
newString(packet, startPos, packet.position()-startPos);
2795 if (debugProtocol != null) {
2799 if (!packet.hasRemaining()) {
2812 final int args = packet.position();
2813 final int faceNum =
getInt2(packet);
2814 final int faceSetNum =
getInt1(packet);
2815 final int faceChecksum =
getInt4(packet);
2816 final String faceName =
getString(packet, packet.remaining()).intern();
2817 if (debugProtocol != null) {
2818 debugProtocol.
debugProtocolWrite(
"recv face2 num="+faceNum+
" set="+faceSetNum+
" checksum="+faceChecksum+
" name="+faceName);
2829 final String full =
getString(packet, packet.remaining());
2830 final String command;
2831 final String message;
2832 final int idx = full.indexOf(
' ');
2837 command = full.substring(0, idx);
2838 message = full.substring(idx+1);
2840 if (debugProtocol != null) {
2841 debugProtocol.
debugProtocolWrite(
"recv failure command="+command+
" message="+message);
2853 final int args = packet.position();
2854 if (packet.hasRemaining()) {
2857 if (debugProtocol != null) {
2870 final int args = packet.position();
2871 final int faceNum =
getInt4(packet);
2872 final int faceSetNum =
getInt1(packet);
2873 final int len =
getInt4(packet);
2874 if (packet.remaining() != len) {
2877 final int faceDataPosition = packet.position();
2878 if (debugProtocol != null) {
2879 debugProtocol.
debugProtocolWrite(
"recv image2 face="+faceNum+
" set="+faceSetNum+
" len="+len);
2881 packet.position(faceDataPosition);
2892 final int args = packet.position();
2893 final int location =
getInt4(packet);
2894 while (packet.hasRemaining()) {
2895 final int tag =
getInt4(packet);
2896 final int flags =
getInt4(packet);
2897 final int weight =
getInt4(packet);
2898 final int faceNum =
getInt4(packet);
2899 final int nameLength =
getInt1(packet);
2900 final String[] names =
getString(packet, nameLength).split(
"\0", 2);
2901 final String name = names[0].intern();
2902 final String namePl = names.length < 2 ? name : names[1].intern();
2903 final int anim =
getInt2(packet);
2904 final int animSpeed =
getInt1(packet);
2905 final int nrof =
getInt4(packet);
2906 final int type =
getInt2(packet);
2907 if (debugProtocol != null) {
2908 debugProtocol.
debugProtocolWrite(
"recv item2 location="+location+
" tag="+tag+
" flags="+flags+
" weight="+weight+
" face="+faceNum+
" name="+name+
" name_pl="+namePl+
" anim="+anim+
" anim_speed="+animSpeed+
" nrof="+nrof+
" type="+type);
2910 fireAddItemReceived(location, tag, flags, weight, faceNum, name, namePl, anim, animSpeed, nrof, type);
2912 if (packet.hasRemaining()) {
2924 final int args = packet.position();
2926 final boolean widthSign = packet.get(packet.position()) ==
'-';
2933 }
while (packet.get(packet.position()) !=
' ');
2939 final boolean heightSign = packet.get(packet.position()) ==
'-';
2946 }
while (packet.get(packet.position()) !=
' ');
2952 final boolean pxSign = packet.get(packet.position()) ==
'-';
2959 }
while (packet.get(packet.position()) !=
' ');
2965 final boolean pySign = packet.get(packet.position()) ==
'-';
2972 }
while (packet.get(packet.position()) !=
' ');
2978 if (debugProtocol != null) {
2979 debugProtocol.
debugProtocolWrite(
"recv magicmap size="+width+
"x"+height+
" player="+px+
"/"+py+
" len="+packet.remaining());
2982 if (packet.remaining() != width*height) {
2986 final byte[][] data =
new byte[height][width];
2987 for (
int y = 0; y < height; y++) {
2988 packet.get(data[y]);
2990 fireMagicMap(-px+(currentMapWidth-1)/2, -py+(currentMapHeight-1)/2, data);
3000 final int args = packet.position();
3001 if (debugProtocol != null) {
3004 if (crossfireUpdateMapListener != null) {
3005 synchronized (crossfireUpdateMapListener.
mapBegin()) {
3006 while (packet.hasRemaining()) {
3007 final int coord =
getInt2(packet);
3010 final int coordType = coord&0xF;
3012 switch (coordType) {
3018 if (debugProtocol != null) {
3021 assert crossfireUpdateMapListener != null;
3022 crossfireUpdateMapListener.
mapScroll(x, y);
3026 if (debugProtocol != null) {
3032 assert crossfireUpdateMapListener != null;
3033 crossfireUpdateMapListener.
mapEnd();
3036 if (debugProtocol != null) {
3047 final int args = packet.position();
3048 if (debugProtocol != null) {
3062 final int args = packet.position();
3063 final String music =
getString(packet, packet.remaining());
3064 if (debugProtocol != null) {
3078 final int args = packet.position();
3079 if (packet.hasRemaining()) {
3082 if (debugProtocol != null) {
3095 final int args = packet.position();
3096 final int pickupOptions =
getInt4(packet);
3097 if (packet.hasRemaining()) {
3100 if (debugProtocol != null) {
3113 final int args = packet.position();
3114 final int tag =
getInt4(packet);
3115 final int weight =
getInt4(packet);
3116 final int faceNum =
getInt4(packet);
3117 final int nameLength =
getInt1(packet);
3118 final String name =
getString(packet, nameLength);
3119 if (packet.hasRemaining()) {
3122 if (debugProtocol != null) {
3123 debugProtocol.
debugProtocolWrite(
"recv player tag="+tag+
" weight="+weight+
" face="+faceNum+
" name="+name);
3135 final int args = packet.position();
3139 }
while (packet.get(packet.position()) !=
' ');
3142 final String text =
getString(packet, packet.remaining());
3144 if (debugProtocol != null) {
3163 final int args = packet.position();
3164 final int startPos = packet.position();
3165 while (packet.hasRemaining() && packet.get(packet.position()) !=
'\n' && packet.get(packet.position()) !=
' ') {
3168 final String infoType =
newString(packet, startPos, packet.position()-startPos);
3169 if (packet.hasRemaining()) {
3172 if (debugProtocol != null) {
3173 debugProtocol.
debugProtocolWrite(
"recv replyinfo type="+infoType+
" len="+packet.remaining());
3177 }
catch (
final IOException ex) {
3188 @SuppressWarnings(
"IfStatementWithIdenticalBranches")
3190 final int args = packet.position();
3191 final List<String> options =
new ArrayList<>();
3192 while (packet.hasRemaining()) {
3193 while (packet.get(packet.position()) ==
' ') {
3196 final int startPos = packet.position();
3197 while (packet.hasRemaining() && packet.get(packet.position()) !=
' ') {
3200 options.add(
newString(packet, startPos, packet.position()-startPos));
3201 if (packet.hasRemaining()) {
3205 if (debugProtocol != null) {
3208 if (options.size()%2 != 0) {
3209 throw new UnknownCommandException(
"odd number of arguments in setup command");
3211 for (
int i = 0; i+1 < options.size(); i += 2) {
3212 final String option = options.get(i);
3213 final String value = options.get(i+1);
3216 if (!value.equals(
"1")) {
3217 throw new UnknownCommandException(
"Error: the server is too old for this client since it does not support the spellmon=1 setup option.");
3231 if (!value.equals(
"1")) {
3232 throw new UnknownCommandException(
"Error: the server is too old for this client since it does not support the newmapcmd=1 setup option.");
3237 if (!value.equals(
"1")) {
3238 throw new UnknownCommandException(
"the server is too old for this client since it does not support the facecache=1 setup option.");
3242 case "extendedTextInfos":
3243 if (!value.equals(
"1")) {
3244 throw new UnknownCommandException(
"the server is too old for this client since it does not support the extendedTextInfos=1 setup option.");
3249 if (!value.equals(
"2")) {
3250 throw new UnknownCommandException(
"the server is too old for this client since it does not support the itemcmd=2 setup option.");
3255 final String[] tmp = value.split(
"x", 2);
3256 if (tmp.length != 2) {
3257 throw new UnknownCommandException(
"the server returned 'setup mapsize "+value+
"'.");
3259 final int thisMapWidth;
3260 final int thisMapHeight;
3262 thisMapWidth = Integer.parseInt(tmp[0]);
3263 thisMapHeight = Integer.parseInt(tmp[1]);
3264 }
catch (
final NumberFormatException ignored) {
3265 throw new UnknownCommandException(
"the server returned 'setup mapsize "+value+
"'.");
3267 if (pendingMapWidth == 0 || pendingMapHeight == 0) {
3268 System.err.println(
"the server sent an unexpected 'setup mapsize "+value+
"'.");
3269 }
else if (pendingMapWidth == thisMapWidth && pendingMapHeight == thisMapHeight) {
3270 pendingMapWidth = 0;
3271 pendingMapHeight = 0;
3273 if (thisMapWidth != preferredMapWidth && thisMapHeight != preferredMapHeight) {
3276 }
else if (pendingMapWidth > thisMapWidth && pendingMapHeight > thisMapHeight) {
3277 pendingMapWidth = 0;
3278 pendingMapHeight = 0;
3280 }
else if (pendingMapWidth > thisMapWidth) {
3282 pendingMapWidth = 0;
3283 pendingMapHeight = 0;
3285 }
else if (pendingMapHeight > thisMapHeight) {
3287 pendingMapWidth = 0;
3288 pendingMapHeight = 0;
3290 }
else if (pendingMapWidth == thisMapWidth) {
3291 final int tmpMapHeight = pendingMapHeight+2;
3292 pendingMapWidth = 0;
3293 pendingMapHeight = 0;
3295 }
else if (pendingMapHeight == thisMapHeight) {
3296 final int tmpMapWidth = pendingMapWidth+2;
3297 pendingMapWidth = 0;
3298 pendingMapHeight = 0;
3300 }
else if (pendingMapWidth <= pendingMapHeight) {
3301 final int tmpMapWidth = pendingMapWidth+2;
3303 pendingMapWidth = 0;
3304 pendingMapHeight = 0;
3308 final int tmpMapHeight = pendingMapHeight+2;
3309 pendingMapWidth = 0;
3310 pendingMapHeight = 0;
3316 if (!value.equals(
"1")) {
3317 throw new UnknownCommandException(
"the server is too old for this client since it does not support the map2cmd=1 setup option.");
3326 if (!value.equals(
"1")) {
3327 throw new UnknownCommandException(
"the server is too old for this client since it does not support the tick=1 setup option.");
3331 case "num_look_objects":
3343 case "extended_stats":
3348 if (value.equals(
"FALSE")) {
3355 method = Integer.parseInt(value);
3356 }
catch (
final NumberFormatException ignored) {
3357 throw new UnknownCommandException(
"the server returned 'setup loginmethod "+value+
"'.");
3359 if (method < 0 || method > 2) {
3360 throw new UnknownCommandException(
"the server returned 'setup loginmethod "+value+
"'.");
3362 loginMethod = method;
3365 case "notifications":
3370 System.err.println(
"Warning: ignoring unknown setup option from server: "+option+
"="+value);
3375 if (options.size() != 2 || !options.get(0).equals(
"mapsize") && !options.get(0).equals(
"num_look_objects")) {
3396 final int args =
packet.position();
3399 if (
packet.hasRemaining()) {
3415 final int args =
packet.position();
3416 final int x =
packet.get();
3417 final int y =
packet.get();
3420 if (
packet.hasRemaining()) {
3437 final int args =
packet.position();
3438 final int x =
packet.get();
3439 final int y =
packet.get();
3440 final int dir =
packet.get();
3447 if (
packet.hasRemaining()) {
3464 while (
packet.hasRemaining()) {
3586 final int args =
packet.position();
3588 if (
packet.hasRemaining()) {
3604 final int args =
packet.position();
3611 final String valName;
3612 final String valNamePl;
3618 int namePlIndex = 0;
3619 while (namePlIndex < nameLength &&
packet.get(
packet.position()+namePlIndex) != 0) {
3623 valNamePl = namePlIndex+1 < nameLength ?
newString(
packet,
packet.position()+namePlIndex+1, nameLength-(namePlIndex+1)) : valName;
3629 if (
packet.hasRemaining()) {
3633 debugProtocol.
debugProtocolWrite(
"recv upditem flags="+flags+
" tag="+tag+
" loc="+valLocation+
" flags="+valFlags+
" weight="+valWeight+
" face="+valFaceNum+
" name="+valName+
" name_pl="+valNamePl+
" anim="+valAnim+
" anim_speed="+valAnimSpeed+
" nrof="+valNrof);
3635 fireUpditemReceived(flags, tag, valLocation, valFlags, valWeight, valFaceNum, valName, valNamePl, valAnim, valAnimSpeed, valNrof);
3644 final int args = packet.position();
3645 final int code =
getInt4(packet);
3646 final int end =
getInt1(packet);
3647 final int stepLength =
getInt2(packet);
3648 final String step = stepLength > 0 ?
getString(packet, stepLength) :
"";
3663 final int args =
packet.position();
3669 if (
packet.hasRemaining()) {
3685 final int args =
packet.position();
3705 sendSetup(
"want_pickup 1",
"faceset 0",
"sound2 3",
"exp64 1",
"map2cmd 1",
"darkness 1",
"newmapcmd 1",
"facecache 1",
"extendedTextInfos 1",
"itemcmd 2",
"spellmon 1",
"tick 1",
"extended_stats 1",
"loginmethod 1",
"notifications 2");
3725 final byte[] loginBytes = login.getBytes(
UTF8);
3726 byteBuffer.put((byte)loginBytes.length);
3727 byteBuffer.put(loginBytes);
3728 final byte[] passwordBytes = password.getBytes(
UTF8);
3729 byteBuffer.put((byte)passwordBytes.length);
3730 byteBuffer.put(passwordBytes);
3731 defaultServerConnection.
writePacket(writeBuffer, byteBuffer.position());
3760 defaultServerConnection.
writePacket(writeBuffer, byteBuffer.position());
3777 defaultServerConnection.
writePacket(writeBuffer, byteBuffer.position());
3794 defaultServerConnection.
writePacket(writeBuffer, byteBuffer.position());
3802 public void sendLock(
final boolean val,
final int tag) {
3810 byteBuffer.put((byte)(val ? 1 : 0));
3811 byteBuffer.putInt(tag);
3812 defaultServerConnection.
writePacket(writeBuffer, byteBuffer.position());
3829 byteBuffer.put((byte)
' ');
3831 defaultServerConnection.
writePacket(writeBuffer, byteBuffer.position());
3847 byteBuffer.putInt(tag);
3848 defaultServerConnection.
writePacket(writeBuffer, byteBuffer.position());
3856 public void sendMove(
final int to,
final int tag,
final int nrof) {
3865 byteBuffer.put((byte)
' ');
3867 byteBuffer.put((byte)
' ');
3869 defaultServerConnection.
writePacket(writeBuffer, byteBuffer.position());
3877 public int sendNcom(
final int repeat, @NotNull
final String command) {
3881 final int thisPacket;
3883 thisPacket =
packet++&0x00FF;
3887 byteBuffer.putShort((
short)thisPacket);
3888 byteBuffer.putInt(repeat);
3889 byteBuffer.put(command.getBytes(
UTF8));
3890 defaultServerConnection.
writePacket(writeBuffer, byteBuffer.position());
3907 byteBuffer.put(text.getBytes(
UTF8));
3908 defaultServerConnection.
writePacket(writeBuffer, byteBuffer.position());
3925 byteBuffer.put(infoType.getBytes(
UTF8));
3926 defaultServerConnection.
writePacket(writeBuffer, byteBuffer.position());
3943 if (options.length <= 0) {
3944 byteBuffer.put((byte)
' ');
3946 for (
final String option : options) {
3947 byteBuffer.put((byte)
' ');
3948 byteBuffer.put(option.getBytes(
UTF8));
3951 defaultServerConnection.
writePacket(writeBuffer, byteBuffer.position());
3960 if (types.length <= 0) {
3971 for (
final int type : types) {
3972 byteBuffer.put((byte)
' ');
3975 defaultServerConnection.
writePacket(writeBuffer, byteBuffer.position());
3983 public void sendVersion(
final int csval,
final int scval, @NotNull
final String vinfo) {
3992 byteBuffer.put((byte)
' ');
3994 byteBuffer.put((byte)
' ');
3995 byteBuffer.put(vinfo.getBytes(
UTF8));
3996 defaultServerConnection.
writePacket(writeBuffer, byteBuffer.position());
4007 byteBuffer.put((byte)
'0');
4009 final String str = Integer.toString(value);
4011 byteBuffer.put(str.getBytes(
"ISO-8859-1"));
4012 }
catch (
final UnsupportedEncodingException ex) {
4013 throw new AssertionError(ex);
4025 final int digit = ch-
'0';
4026 if (digit < 0 || digit > 9) {
4037 final int preferredMapWidth2 = Math.max(1, preferredMapWidth|1);
4038 final int preferredMapHeight2 = Math.max(1, preferredMapHeight|1);
4039 if (this.preferredMapWidth == preferredMapWidth2 && this.preferredMapHeight == preferredMapHeight2) {
4043 this.preferredMapWidth = preferredMapWidth2;
4044 this.preferredMapHeight = preferredMapHeight2;
4055 if (this.currentMapWidth == currentMapWidth && this.currentMapHeight == currentMapHeight) {
4094 public void connect(@NotNull
final String hostname,
final int port) {
4099 defaultServerConnection.
connect(hostname, port);
4136 System.err.println(
"Warning: connection state is "+
clientSocketState+
" when switching to state "+nextState+
", expecting state "+prevState);
4156 byteBuffer.put(name.getBytes(
UTF8));
4157 defaultServerConnection.
writePacket(writeBuffer, byteBuffer.position());
4161 if (tmpAccountName != null) {
4170 public void sendAccountLink(
final int force, @NotNull
final String login, @NotNull
final String password) {
4179 byteBuffer.put((byte)force);
4180 final byte[] loginBytes = login.getBytes(
UTF8);
4181 byteBuffer.put((byte)loginBytes.length);
4182 byteBuffer.put(loginBytes);
4183 final byte[] passwordBytes = password.getBytes(
UTF8);
4184 byteBuffer.put((byte)passwordBytes.length);
4185 byteBuffer.put(passwordBytes);
4186 defaultServerConnection.
writePacket(writeBuffer, byteBuffer.position());
4204 final byte[] loginBytes = login.getBytes(
UTF8);
4205 byteBuffer.put((byte)loginBytes.length);
4206 byteBuffer.put(loginBytes);
4207 final byte[] passwordBytes = password.getBytes(
UTF8);
4208 byteBuffer.put((byte)passwordBytes.length);
4209 byteBuffer.put(passwordBytes);
4210 defaultServerConnection.
writePacket(writeBuffer, byteBuffer.position());
4227 final byte[] loginBytes = login.getBytes(
UTF8);
4228 byteBuffer.put((byte)loginBytes.length);
4229 byteBuffer.put(loginBytes);
4230 final byte[] passwordBytes = password.getBytes(
UTF8);
4231 byteBuffer.put((byte)passwordBytes.length);
4232 byteBuffer.put(passwordBytes);
4233 defaultServerConnection.
writePacket(writeBuffer, byteBuffer.position());
4250 final byte[] currentPasswordBytes = currentPassword.getBytes(
UTF8);
4251 byteBuffer.put((byte)currentPasswordBytes.length);
4252 byteBuffer.put(currentPasswordBytes);
4253 final byte[] newPasswordBytes = newPassword.getBytes(
UTF8);
4254 byteBuffer.put((byte)newPasswordBytes.length);
4255 byteBuffer.put(newPasswordBytes);
4256 defaultServerConnection.
writePacket(writeBuffer, byteBuffer.position());
4266 private static int getInt1(@NotNull
final ByteBuffer byteBuffer) {
4267 return byteBuffer.get()&0xFF;
4276 private static int getInt2(@NotNull
final ByteBuffer byteBuffer) {
4277 return byteBuffer.getShort()&0xFFFF;
4286 private static int getInt4(@NotNull
final ByteBuffer byteBuffer) {
4287 return byteBuffer.getInt();
4296 private static long getInt8(@NotNull
final ByteBuffer byteBuffer) {
4297 return byteBuffer.getLong();
4308 private static String
getString(@NotNull
final ByteBuffer byteBuffer,
final int len) {
4309 final byte[] tmp =
new byte[len];
4310 byteBuffer.get(tmp);
4311 return new String(tmp,
UTF8);
4323 final int position = byteBuffer.position();
4324 final int remaining = byteBuffer.remaining();
4326 for (len = 0; len < remaining; len++) {
4327 if (byteBuffer.get(position+len) == delimiter) {
4331 final byte[] tmp =
new byte[len];
4332 byteBuffer.get(tmp);
4333 if (len < remaining) {
4336 return new String(tmp,
UTF8);
4345 private static String
hexDump(@NotNull
final ByteBuffer byteBuffer) {
4346 final int len = byteBuffer.limit();
4347 final byte[] data =
new byte[len];
4348 for (
int i = 0; i < len; i++) {
4349 data[i] = byteBuffer.get(i);
4402 protected void fireAddAnimation(
final int animation,
final int flags, @NotNull
final int[] faces) {
4408 protected void fireMagicMap(
final int x,
final int y, @NotNull
final byte[][] data) {
4435 final String infoType;
static final int CS_STAT_GOLEM_HP
The golem's hitpoints, 0 if no golem.
void sendPendingRequestInfo()
Sends the next asynchronous "requestinfo" packet if possible.
void cmdMap2CoordinateClearSpace(final int x, final int y, final int len)
Processes the payload data for a map2 coordinate "clear_space" sub-command.
void sendVersion(final int csval, final int scval, @NotNull final String vinfo)
Sends a "version" command to the server.the client version number the server version number the clien...
void cmdMap2CoordinateLayer3(@NotNull final ByteBuffer packet, @NotNull final Location location, final int face)
Processes the additional payload data for a map2 coordinate "layer" sub-command having 4 bytes payloa...
void processAddmeFailed(@NotNull final ByteBuffer packet)
Processes an 'account_failed' server command.
Builder for StartingMap instances while parsing a "replyinfo startingmap" response packet...
ClassRaceInfo finish()
Finishes parsing an entry an returns the ClassRaceInfo for the entry.
void writePacket(@NotNull final byte[] packet, final int length)
Writes a Crossfire Message on the socket, so it is sent to the server.
VERSION
"version" protocol commands are being exchanged.
void processExpTableReplyinfo(@NotNull final ByteBuffer packet)
Processes a "replyinfo exp_table" block.
void fireUpditemReceived(final int flags, final int tag, final int valLocation, final int valFlags, final int valWeight, final int valFaceNum, @NotNull final String valName, @NotNull final String valNamePl, final int valAnim, final int valAnimSpeed, final int valNrof)
Abstract base class for CrossfireServerConnection implementing classes.
void addSpell(final int tag, final int level, final int castingTime, final int mana, final int grace, final int damage, final int skill, final int path, final int faceNum, @NotNull final String spellName, @NotNull final String message)
Adds a new spell.
static int [] getAllTypes()
Returns all defined message types.
static final int CS_STAT_RACE_CHA
The race's maximum charisma primary stat.
static void parseClassRaceInfoStats(@NotNull final ByteBuffer packet, @NotNull final ClassRaceInfoBuilder rb)
Parses a "stats" entry of a "replyinfo race_info" or "replyinfo class_info" packet.
void processGoodbye(@NotNull final ByteBuffer packet)
Processes a 'goodbye' server command.
static final int CS_STAT_DEX
The Dexterity Primary stat.
int COORD_LAYER3
Face information for layer 3.
static final int CS_STAT_SPELL_ATTUNE
Attuned spell paths of a spell.
final NumLookObjects numLookObjects
The NumLookObjects instance for negotiating the size of the ground view.
void processMagicMap(@NotNull final ByteBuffer packet)
Processes a 'magicmap' server command.
void start()
Starts operation.
int COORD_LAYER7
Face information for layer 7.
int loginMethod
The login method version supported by the server we're connected to.
void processDrawExtInfo(@NotNull final ByteBuffer packet)
Processes a 'drawextinfo' server command.
Encapsulates the message type numbers for drawextinfo messages.
void sendExamine(final int tag)
Sends an "examine" command to the server.the item to examine
static void parseClassRaceInfoChoice(@NotNull final ByteBuffer packet, @NotNull final ClassRaceInfoBuilder rb)
Parses a "choice" entry of a "replyinfo race_info" or "replyinfo class_info" packet.
void sendLock(final boolean val, final int tag)
Sends a "lock" command to the server.whether to lock the item the item to lock
static long getInt8(@NotNull final ByteBuffer byteBuffer)
Extracts and removes an 8 byte integer from a ByteBuffer at it's current position.
int COORD_LAYER6
Face information for layer 6.
static final int RESIST_TYPES
The total number of resistances.
void processSetupNumLookObjects(@NotNull final String value)
Called when a "setup num_look_objects" response has been received from the server.
void updateSpell(final int flags, final int tag, final int mana, final int grace, final int damage)
Updates spell information.
void processRaceListReplyinfo(@NotNull final ByteBuffer packet)
Processes a "replyinfo race_list" block.
void processSmooth(@NotNull final ByteBuffer packet)
Processes a 'smooth' server command.
GuiStateManager getGuiStateManager()
void processClassListReplyinfo(@NotNull final ByteBuffer packet)
Processes a "replyinfo class_list" block.
void sendAddme()
Sends an "addme" command to the server.
NewCharInfo finish()
Finished parsing and returns the NewCharInfo instance for the parsed entry.
static final byte [] VERSION_PREFIX
The command prefix for the "version" command.
void fireAddAnimation(final int animation, final int flags, @NotNull final int[] faces)
static final int CS_STAT_TITLE
The Title stat.
static final int CS_STAT_SPELL_DENY
Denied spell paths of a spell.
void processSound2(@NotNull final ByteBuffer packet)
Processes a 'sound2' server command.
static final int CS_STAT_RANGE
The Range stat - this is what is currently readied by the player to fire.
int UPD_FACE
The update flags value for face updates.
void updateQuest(final int code, final boolean end, @NotNull final String step)
Updates quest information.
static final Charset UTF8
The Charset used for parsing or encoding strings received from or sent to the Crossfire server...
SmoothFaces getSmoothFaces()
int TYPE_COORDINATE
Normal coordinate.
void processAddKnowledge(@NotNull final ByteBuffer packet)
Processes an "addacknowledge" block.
int packet
The packet id for the next "ncom" command to send.
REQUESTINFO
"requestinfo" protocol commands are being exchanged.
void sendLookat(final int dx, final int dy)
Sends a "lookat" command to the server.the x-coordinate in tiles, relative to the player the y-coordi...
static final int CS_STAT_APPLIED_CON
The constitution primary stat changes due to gear or skills.
static final int CS_STAT_RESIST_START
Beginning index of the resistances.
void firePickupChanged(final int pickupOptions)
void processUpdItem(@NotNull final ByteBuffer packet)
Processes an 'upditem' server command.
void cmdMap2CoordinateDarkness(@NotNull final ByteBuffer packet, final int x, final int y, final int len)
Processes the payload data for a map2 coordinate "darkness" sub-command.
static final byte [] CREATE_PLAYER_PREFIX
The command prefix for the "createplayer" command.
void removeClientSocketListener(@NotNull final ClientSocketListener clientSocketListener)
Removes a ClientSocketListener to notify.the client socket listener to remove
final Model model
The Model instance that is updated.
int UPD_ANIMSPEED
The update flags value for animation speed updates.
void notifyPacketWatcherListenersShortInt(@NotNull final ByteBuffer packet, final int args)
Notifies all ReceivedPacketListeners about a packet having a short and an in value as parameters...
static final byte [] APPLY_PREFIX
The command prefix for the "apply" command.
void processNewMap(@NotNull final ByteBuffer packet)
Processes a 'newmap' server command.
static final byte [] REPLY_PREFIX
The command prefix for the "reply" command.
int COORD_LAYER1
Face information for layer 1.
static final int CS_STAT_BASE_POW
The power primary stat without boosts or depletions.
void processReplyInfo(@NotNull final ByteBuffer packet)
Processes a 'replyinfo' server command.
void drawextinfo(final int color, final int type, final int subtype, final String message)
Pretends that a drawextinfo message has been received.the message type the message subtype the messag...
void fireMapAnimation(@NotNull final Location location, final int animationNum, final int animationType)
void setStatInt2(final int stat, final short param)
Updates a stat value with a two-byte int value.
void faceReceived(final int faceNum, final int faceSetNum, @NotNull final ByteBuffer packet)
Notifies the askface manager that image information have been received from the server.
CONNECT_FAILED
A connection could not be established.
void updateSmoothFace(final int face, final int smoothFace)
Updates smooth face information.
static final int CS_STAT_POW
The Power Primary stat.
static final int ACL_FACE
Parameter type in the "accountplayers" command.
SETUP
"setup" protocol commands are being exchanged.
void processExtendedInfoSet(@NotNull final ByteBuffer packet)
Processes an 'ExtendedInfoSet' server command.
void fireDelitemReceived(@NotNull final int[] tags)
void clearFailure()
Inform the various failure listeners that they can clean the last displayed failure.
void processPlayer(@NotNull final ByteBuffer packet)
Processes a 'pickup' server command.
static final int CS_STAT_APPLIED_INT
The integer primary stat changes due to gear or skills.
static final Pattern PATTERN_SPACE
Pattern to split a string by spaces.
void fireMapSmooth(@NotNull final Location location, final int smooth)
void processVersion(@NotNull final ByteBuffer packet)
Processes a 'version' server command.
void debugProtocolWrite(@NotNull final CharSequence str)
Writes a message to the debug protocol.
final List< String > pendingRequestInfos
Pending "requestinfo" commands that will be sent as soon sendingRequestInfo is unset.
void addAnimation(int animation, int flags, @NotNull int[] faces)
An "addanim" command has been received.
void processPacket(@NotNull final ByteBuffer packet)
Processes a received packet.
void notifyPacketWatcherListenersMixed(@NotNull final ByteBuffer packet, final int args)
Notifies all ReceivedPacketListeners about a packet having mixed parameters.
int COORD_LAYER2
Face information for layer 2.
static int getInt4(@NotNull final ByteBuffer byteBuffer)
Extracts and removes a 4 byte integer from a ByteBuffer at it's current position. ...
void sendAccountLink(final int force, @NotNull final String login, @NotNull final String password)
Sends a request to add an existing character to an account.0 to allow failure, 1 to force in certain ...
static final int ACL_LEVEL
Parameter type in the "accountplayers" command.
static final int CS_NUM_SKILLS
CS_NUM_SKILLS does not match how many skills there really are - instead, it is used as a range of val...
void processImage2(@NotNull final ByteBuffer packet)
Processes an 'image2' server command.
General information for creating new characters.
int pendingMapHeight
The map height that is being negotiated with the server.
int FACE_ANIMATION
Bit value whether this is a face or an animation.
int COORD_LAYER4
Face information for layer 4.
Implements the map model which is shown in the map and magic map views.
int pendingMapWidth
The map width that is being negotiated with the server.
Builder for CharacterInformation instances while parsing an "accountplayers" packet.
static final byte [] TOGGLEEXTENDEDTEXT_PREFIX
The command prefix for the "toggleextendedtext" command.
void setPreferredNumLookObjects(final int preferredNumLookObjects)
Sets the maximum number of objects in the ground view.Must not be called in connected state...
int UPD_FLAGS
The update flags value for flags updates.
static final int CS_STAT_HP
The Hit Points stat.
static final int CS_STAT_LEVEL
The Global Level stat.
void processAddSpell(@NotNull final ByteBuffer packet)
Processes an 'addspell' server command.
int COORD_DARKNESS
Darkness information.
KnowledgeManager getKnowledgeManager()
void sendAccountCreate(@NotNull final String login, @NotNull final String password)
Sends a request to create a new account.the account login the account password
void clearSkills()
Clears all skills.
Writer debug information to a log file.
void setSimpleWeaponSpeed(final boolean simpleWeaponSpeed)
Sets whether the CS_STAT_WEAP_SP value contains the weapon speed directly.
void mapEnd()
Parsing of "map2" has been finished.
void setPreferredMapSize(final int preferredMapWidth, final int preferredMapHeight)
Sets the preferred map size.the preferred map width in tiles; must be odd the preferred map height in...
void sendQueuedRequestinfo(@NotNull final String infoType)
Sends a "requestinfo" packet asynchronously.
static final int CS_STAT_MAXHP
The Maximum Hit Points stat.
static final int CS_STAT_RACE_WIS
The race's maximum wisdom primary stat.
static final int ACL_PARTY
Parameter type in the "accountplayers" command.
void processMusic(@NotNull final ByteBuffer packet)
Processes a 'music' server command.
final DefaultServerConnection defaultServerConnection
The physical server connection.
Manages all known spells.
static String getStringDelimiter(@NotNull final ByteBuffer byteBuffer, final char delimiter)
Extracts and removes a string from a ByteBuffer at it's current position.
void setName(@NotNull final String name)
Sets the human readable stat name.
int preferredMapHeight
The map height in tiles that is negotiated with the server.
static final int CS_STAT_DAM
The Damage stat.
static final int CS_STAT_STR
The Strength Primary stat.
void processAddQuest(@NotNull final ByteBuffer packet)
Processes an 'addquest' server command.
void deleteSpell(final int tag)
Deletes a spell.
static final int CS_STAT_AC
The Armor Class stat.
void processAddmeSuccess(@NotNull final ByteBuffer packet)
Processes an 'account_success' server command.
void mapScroll(int dx, int dy)
Part of "map2" parsing: scroll the map view.
static final int CS_STAT_FOOD
The Food stat.
static final int CS_STAT_WIS
The Wisdom Primary stat.
boolean connected
Whether the current client socket state is ClientSocketState#CONNECTED.
void setStatSkill(final int stat, final int level, final long experience)
Updates a stat value with a skill value.
Collection< StartingMap > finish()
Finishes parsing.
void fireMapClear(final int x, final int y)
One of the two most important classes, ServerConnection performs most of the network-related work...
static final int CS_STAT_BASE_INT
The integer primary stat without boosts or depletions.
int UPD_NAME
The update flags value for name updates.
static String getString(@NotNull final ByteBuffer byteBuffer, final int len)
Extracts and removes a string from a ByteBuffer at it's current position.
static final int CS_STAT_SP
The Spell Points stat.
void processStats(@NotNull final ByteBuffer packet)
Processes a 'stats' server command.
CONNECTING
The socket is being established.
void mapAnimationSpeed(@NotNull Location location, int animationSpeed)
Part of "map2" parsing: set the animation speed.
static final int ACL_MAP
Parameter type in the "accountplayers" command.
static final int UPD_SP_GRACE
Flag for updspell command: grace is present.
static final int DEFAULT_MAP_HEIGHT
The default map height when no "setup mapsize" command has been sent.
final byte [] writeBuffer
Buffer to build commands to send.
void processSound(@NotNull final ByteBuffer packet)
Processes a 'sound' server command.
int ANIM_TYPE_MASK
The mask for extracting the animation type.
static final byte [] SETUP_PREFIX
The command prefix for the "setup" command.
void setPreferredNumLookObjects(final int preferredNumLookObjects)
Sets the preferred number of ground items.
static final int UPD_SP_MANA
Flag for updspell command: mana is present.
void processAnim(@NotNull final ByteBuffer packet)
Processes an 'anim' server command.
static final Pattern PATTERN_DOT
Pattern to split a string by ":".
Builder for ClassRaceInfo instances while parsing an "replyinfo race_info" packet.
static String extractCommand(@NotNull final ByteBuffer packet)
Returns the command string for a received packet.
void setArchName(@NotNull final byte[] archName)
Starts a new starting map entry.
static final int CS_STAT_RACE_CON
The race's maximum constitution primary stat.
void processNewCharInfoReplyinfo(@NotNull final ByteBuffer packet)
Processes a "replyinfo newcharinfo" block.
static final byte [] ACCOUNT_NEW_PREFIX
The command prefix for the "accountnew" command.
static final byte [] ACCOUNT_LOGIN_PREFIX
The command prefix for the "accountlogin" command.
Combines all model classes that are updated.
ACCOUNT_INFO
The client is connected, and account information is being exchanged.
void waitForCurrentNumLookObjectsValid()
Waits until getCurrentNumLookObjects() is stable.
void setStatString(final int stat, @NotNull final String param)
Updates a stat value with a string value.
void disconnect(@NotNull final String reason)
Disconnects from the server.Does nothing if not connected. the reason for the disconnect ...
static final byte [] LOCK_PREFIX
The command prefix for the "lock" command.
DefaultCrossfireServerConnection(@NotNull final Model model, @Nullable final DebugWriter debugProtocol, @NotNull final String version)
Creates a new instance.
void processSetup(@NotNull final ByteBuffer packet)
Processes a 'replyinfo' server command.
static final int CS_STAT_WEIGHT_LIM
The Weight Limit stat.
void sendAccountCharacterCreate(@NotNull final String login, @NotNull final String password)
Sends a request to create a new character associated to the account.the character's name the characte...
int preferredMapWidth
The map width in tiles that is negotiated with the server.
void setMsg(@NotNull final String msg)
Sets the long description.
static final byte [] MOVE_PREFIX
The command prefix for the "move" command.
static final int CS_STAT_APPLIED_STR
The strength primary stat changes due to gear or skills.
void addClientSocketListener(@NotNull final ClientSocketListener clientSocketListener)
Adds a ClientSocketListener to notify.the client socket listener to add
void sendRequestinfo(@NotNull final String infoType)
Sends a "requestinfo" command to the server.the info type to request
static final int CS_STAT_BASE_STR
The strength primary stat without boosts or depletions.
static final int CS_STAT_GOLEM_MAXHP
The golem's maximum hitpoints, 0 if no golem.
void setName(@NotNull final String name)
Sets the name of the current entry.
A choice for character creation.
static int getInt1(@NotNull final ByteBuffer byteBuffer)
Extracts and removes a 1 byte integer from a ByteBuffer at it's current position. ...
int currentMapHeight
The currently active map height.
void fireCommandQueryReceived(@NotNull final String prompt, final int queryType)
void magicMap(int x, int y, byte[][] data)
Part of "magicmap" parsing: set the magic map color.
final DebugWriter debugProtocol
The appender to write protocol commands to.
void processAccountPlayers(@NotNull final ByteBuffer packet)
Processes an 'accountplayers' server command.
static void parseNewCharInfoValues(@NotNull final NewCharInfoBuilder newCharInfoBuilder, @NotNull final String variableName, @NotNull final String values)
Parses a 'V' entry of a "replyinfo newcharinfo" packet.
static final int CS_STAT_SKILLINFO
CS_STAT_SKILLINFO is used as the starting index point.
void notifyPacketWatcherListenersShortArray(@NotNull final ByteBuffer packet, final int args)
Notifies all ReceivedPacketListeners about a packet having an array of short values as parameters...
int currentMapWidth
The currently active map width.
Interface defining constants for the "map2" Crossfire protocol message.
static void processImageInfoReplyinfo(@NotNull final ByteBuffer packet)
Processes a "replyinfo image_info" block.
void sendAccountLogin(@NotNull final String login, @NotNull final String password)
Asks for an account login.the account login the account password
void processUpdSpell(@NotNull final ByteBuffer packet)
Processes an 'updspell' server command.
static final int CS_STAT_CON
The Constitution Primary stat.
static final int CS_STAT_RACE_STR
The race's maximum strength primary stat.
final ClientSocketListener clientSocketListener
The ClientSocketListener attached to the server socket.
int getCurrentNumLookObjects()
Returns the current number of ground items.
void fireNewMap()
Notifies all listeners that a "newmap" command has been received.
static final int CS_STAT_APPLIED_DEX
The dexterity primary stat changes due to gear or skills.
void sendReply(@NotNull final String text)
Sends a "reply" command to the server.the text to reply
static final Pattern PATTERN_BAR
Pattern to split a string by "|".
int COORD_LAYER9
Face information for layer 9.
Object mapBegin()
Parsing of a "map2" command has been started.
static final int INFO_MAP_NAME
Proper name of a "replyinfo startingmap" entry.
void fireMapAnimationSpeed(@NotNull final Location location, final int animSpeed)
static String hexDump(@NotNull final byte[] data, final int start, final int end)
Returns a hex dump of a part of a byte array.
static String hexDump(@NotNull final ByteBuffer byteBuffer)
Returns a hex-dump of a ByteBuffer.
void removeClientSocketListener(@NotNull final ClientSocketListener clientSocketListener)
Removes a ClientSocketListener to notify.the client socket listener to remove
static final byte [] LOOKAT_PREFIX
The command prefix for the "lookat" command.
void notifyPacketWatcherListenersNoData(@NotNull final ByteBuffer packet, final int args)
Notifies all ReceivedPacketListeners about a packet having unknown parameters.
static final int ACL_RACE
Parameter type in the "accountplayers" command.
static final int INFO_MAP_ARCH_NAME
Archetype name of a "replyinfo startingmap" entry.
int COORD_OFFSET
Offset for coordinate values in map2 command.
static void parseNewCharInfoInformational(@NotNull final String variableName, @NotNull final String values)
Parses an 'I' entry of a "replyinfo newcharinfo" packet.
void processItem2(@NotNull final ByteBuffer packet)
Processes an 'item2' server command.
static void parseNewCharInfoValue(@NotNull final NewCharInfoBuilder newCharInfoBuilder, final boolean required, @NotNull final String variableName, @NotNull final String values)
Parses an 'R' or 'O' entry of a "replyinfo newcharinfo" packet.
static final byte [] REQUESTINFO_PREFIX
The command prefix for the "requestinfo" command.
void fireCommandSoundReceived(final int x, final int y, final int num, final int type)
void addSkill(final int id, @NotNull final String skillName, final int face)
Adds a new skill to the list of known skills.
An UnknownCommandException is generated whenever an unknown message packet is received from the serve...
int UPD_LOCATION
The update flags value for location updates.
void waitForCurrentNumLookObjectsValid()
Waits until getCurrentNumLookObjects() is stable.
void sendAccountPassword(@NotNull final String currentPassword, @NotNull final String newPassword)
Sends a request to change the account's password.current account password new account password ...
void processPickup(@NotNull final ByteBuffer packet)
Processes a 'pickup' server command.
int getCurrentNumLookObjects()
Returns the currently negotiated setup value of "num_look_objects".
void fireCommandComcReceived(final int packetNo, final int time)
void cmdMap2CoordinateLayer4(@NotNull final ByteBuffer packet, @NotNull final Location location, final int face)
Processes the additional payload data for a map2 coordinate "layer" sub-command having 4 bytes payloa...
void fireCommandSound2Received(final int x, final int y, final int dir, final int volume, final int type, @NotNull final String action, @NotNull final String name)
void fireStartAccountList(@NotNull final String accountName)
static final int CS_STAT_RACE_INT
The race's maximum intelligence primary stat.
static final int CS_STAT_MAXGRACE
The Maximum Grace stat.
void fireMusicReceived(@NotNull final String music)
static final int ACL_FACE_NUM
Parameter type in the "accountplayers" command.
void processFailure(@NotNull final ByteBuffer packet)
Processes a 'failure' server command.
Interface for listeners interested in ClientSocket related events.
void sendApply(final int tag)
Sends an "apply" command to the server.the item to apply
void processSkillInfoReplyinfo(@NotNull final ByteBuffer packet)
Processes a "replyinfo skill_info" block.
static final int CS_STAT_RACE_DEX
The race's maximum dexterity primary stat.
void fireTick(final int tickNo)
int COORD_LAYER8
Face information for layer 8.
static final int CS_STAT_BASE_CON
The constitution primary stat without boosts or depletions.
void fireMagicMap(final int x, final int y, @NotNull final byte[][] data)
static final int CS_STAT_CHA
The Charisma Primary stat.
void negotiateMapSize(final int mapWidth, final int mapHeight)
Requests a change of the map size from the server.
void addKnowledge(final int index, @NotNull final String type, @NotNull final String title, final int face)
void sendAskface(final int faceNum)
Sends an "askface" command.the face number to request
void processFace2(@NotNull final ByteBuffer packet)
Processes a 'face2' server command.
Default implementation of CrossfireServerConnection.
void fireFaceReceived(final int faceNum, final int faceSetNum, final int faceChecksum, @NotNull final String faceName)
void stop()
Stops operation.if stopping was interrupted
void mapFace(@NotNull Location location, int faceNum)
Part of "map2" parsing: set the face of a cell.
ExperienceTable getExperienceTable()
static final int CS_STAT_EXP64
The Global Experience (64bit encoding) stat.
void notifyPacketWatcherListenersIntArray(@NotNull final ByteBuffer packet, final int args)
Notifies all ReceivedPacketListeners about a packet having an array of int values as parameters...
void sendAccountPlay(@NotNull final String name)
Sends a request to play a character from an account.the character's name to play
void processClassRaceInfoReplyinfo(@NotNull final ByteBuffer packet, final boolean raceInfo)
Processes a "replyinfo race_info" or "replyinfo class_info" block.
void fireMapDarkness(final int x, final int y, final int darkness)
void fireFailure(@NotNull final String command, @NotNull final String arguments)
void fireMapFace(@NotNull final Location location, final int face)
static final int CS_STAT_APPLIED_CHA
The charisma primary stat changes due to gear or skills.
void setCrossfireUpdateMapListener(@Nullable final CrossfireUpdateMapListener listener)
Sets a listener to be notified about map changes.At most one such listener may be set...
static int getInt2(@NotNull final ByteBuffer byteBuffer)
Extracts and removes a 2 byte integer from a ByteBuffer at it's current position. ...
void cmdMap2CoordinateLayer(@NotNull final ByteBuffer packet, final int x, final int y, final int len, final int layer)
Processes the payload data for a map2 coordinate "layer" sub-command.
static final int CS_STAT_SPELL_REPEL
Repelled spell paths of a spell.
static final int CS_STAT_WC
The Weapon Class stat.
void setClientSocketState(@NotNull final ClientSocketState clientSocketState)
Sets the new ClientSocketState.
void cmdMap2Coordinate(@NotNull final ByteBuffer packet, final int x, final int y)
Processes the payload data for a map2 coordinate command.
static final int UPD_SP_DAMAGE
Flag for updspell command: damage is present.
void setDescription(@NotNull final String description)
Sets the description of the current entry.
void setClientSocketState(@NotNull final ClientSocketState prevState, @NotNull final ClientSocketState nextState)
Updates the clientSocketState.
CrossfireUpdateMapListener crossfireUpdateMapListener
The CrossfireUpdateMapListener to be notified.
static final int CS_STAT_EXP
The Global Experience (32bit encoding) stat.
void setCurrentMapSize(final int currentMapWidth, final int currentMapHeight)
Sets the current map size as negotiated with the server.
void mapAnimation(@NotNull Location location, int animationNum, int animationType)
Part of "map2" parsing: set the animation of a cell.
static final int CS_STAT_BASE_WIS
The wisdom primary stat without boosts or depletions.
void processDelSpell(@NotNull final ByteBuffer packet)
Processes a 'delspell' server command.
void connected()
Called after the server connection has been established.
One possible class or race for character creation.
static final int CS_STAT_BASE_DEX
The dexterity primary stat without boosts or depletions.
static final int INFO_MAP_DESCRIPTION
Description of a "replyinfo startingmap" entry.
int COORD_LAYER5
Face information for layer 5.
void setStatInt4(final int stat, final int param)
Updates a stat value with a four-byte int value.
int COORD_CLEAR_SPACE
Clear a square.
int ANIM_MASK
The mask for extracting the animation ID.
void addClientSocketListener(@NotNull final ClientSocketListener clientSocketListener)
Adds a ClientSocketListener to notify.the client socket listener to add
void fireAddItemReceived(final int location, final int tag, final int flags, final int weight, final int faceNum, final String name, final String namePl, final int anim, final int animSpeed, final int nrof, final int type)
Builder for NewCharInfo instances while parsing a "replyinfo newcharinfo" response packet...
Interface defining constants for the "upditem" Crossfire protocol message.
void disconnect(@NotNull final String reason)
Disconnects from the server.Does nothing if not connected. the reason for the disconnect ...
void firePlayerReceived(final int tag, final int weight, final int faceNum, @NotNull final String name)
CharacterInformation parseAccountPlayer(@NotNull final ByteBuffer packet, @NotNull final AccountPlayerBuilder accountPlayerBuilder)
Processes one account entry of an 'accountplayers' server command.
void addQuest(final int code, @NotNull final String title, final int face, final boolean replay, final int parent, final boolean end, @NotNull final String description)
Adds a new quest.
ADDME
"addme" protocol commands are being exchanged.
void sendMark(final int tag)
Sends a "mark" command to the server.the item to mark
void addKnowledgeType(@NotNull final String type, @NotNull final String name, final int face, final boolean canAttempt)
static final int CS_STAT_RACE_POW
The race's maximum power primary stat.
static String newString(final ByteBuffer byteBuffer, final int start, final int len)
Extracts a string from a ByteBuffer range.
void cmdReplyinfo(@NotNull final String infoType, final ByteBuffer packet)
Handles the replyinfo server to client command.
int UPD_ANIM
The update flags value for animation updates.
static final byte [] ACCOUNT_ADD_PLAYER_PREFIX
The command prefix for the "accountaddplayer" command.
void fireSelectCharacter(@NotNull final String accountName, @NotNull final String characterName)
void processDelInv(@NotNull final ByteBuffer packet)
Processes a 'delinv' server command.
int UPD_NROF
The update flags value for nrof updates.
static final byte [] ASKFACE_PREFIX
The command prefix for the "askface" command.
void processExtendedTextSet(@NotNull final ByteBuffer packet)
Processes an 'ExtendedTextSet' server command.
static final int CS_STAT_INT
The Intelligence Primary stat.
int UPD_WEIGHT
The update flags value for weight updates.
void mapSmooth(@NotNull Location location, int smooth)
Part of "map2" parsing: set the smooth level.
void sendSetup(@NotNull final String... options)
Sends a "setup" command to the server.the option/value pairs to send
void notifyPacketWatcherListenersStats(final int stat, @NotNull final Object... args)
Notifies all ReceivedPacketListeners about a packet having stat parameters.
void processKnowledgeInfoReplyinfo(@NotNull final ByteBuffer packet)
Processes a "replyinfo knowledge_info" block.
static final int CS_STAT_FLAGS
The various flags used in stats.
void sendMove(final int to, final int tag, final int nrof)
Sends a "move" command to the server.the destination location the item to move the number of items to...
static final byte [] EXAMINE_PREFIX
The command prefix for the "examine" command.
SpellsManager getSpellsManager()
void processMap2(@NotNull final ByteBuffer packet)
Processes a 'map2' server command.
String accountName
The account name.
This is the representation of all the statistics of a player, like its speed or its experience...
void notifyPacketWatcherListenersAscii(@NotNull final ByteBuffer packet, final int args)
Notifies all ReceivedPacketListeners about a packet having ascii parameters.
static final int CS_STAT_WEAP_SP
The Weapon Speed stat.
AskfaceFaceQueue getAskfaceFaceQueue()
void setClientSocketState(@NotNull final ClientSocketState clientSocketState)
Called whenever the client socket state has changed.
Negotiates the size of the ground view in items with the Crossfire server.
void putDecimal(final int value)
Appends an integer in decimal ASCII representation to byteBuffer.
static int parseDigit(final byte ch)
Parses a character into an integer.
void processMapExtended(@NotNull final ByteBuffer packet)
Processes a 'mapextended' server command.
static final int CS_STAT_MAXSP
The Maximum Spell Points stat.
void processUpdQuest(@NotNull final ByteBuffer packet)
Processes an 'updquest' server command.
static final int ACL_CLASS
Parameter type in the "accountplayers" command.
void fireDelinvReceived(final int tag)
void processTick(@NotNull final ByteBuffer packet)
Processes a 'tick' server command.
static final int CS_STAT_APPLIED_POW
The power primary stat changes due to gear or skills.
ClientSocketState clientSocketState
The current connection state.
final ByteBuffer byteBuffer
A byte buffer using writeBuffer to store the data.
void processQuery(@NotNull final ByteBuffer packet)
Processes a 'pickup' server command.
static final byte [] ACCOUNT_PLAY_PREFIX
The command prefix for the "accountplay" command.
void mapClear(int x, int y)
Part of "map2" parsing: clear a cell.
String getAccountName()
Returns the current account name.the current account name ornull
Connection progress states of the Crossfire server connection.
static final byte [] MARK_PREFIX
The command prefix for the "mark" command.
int TYPE_SCROLL
Scroll information.
String sendingRequestInfo
If non-.
void processComc(@NotNull final ByteBuffer packet)
Processes a 'comc' server command.
QuestsManager getQuestsManager()
Interface for listeners interested in map related commands.
void fireAddAccount(@NotNull final CharacterInformation characterInformation)
static final int CS_STAT_SPEED
The Speed stat.
void start()
Starts operation.
static final byte [] ACCOUNT_PASSWORD_PREFIX
The command prefix for the "accountpw" command.
void setExpTable(@NotNull final long[] expTable)
Updates the experience table information.
static final byte [] NCOM_PREFIX
The command prefix for the "ncom" command.
void newMap(int mapWidth, int mapHeight)
A "newmap" command has been received.
void stop()
Stops operation.
int ANIM_TYPE_SHIFT
The lowest bit of the animation type.
NewCharacterInformation getNewCharacterInformation()
Returns the NewCharacterInformation for creating new characters.
void setStatInt8(final int stat, final long param)
Updates a stat value with an eight-byte int value.
static final int CS_STAT_GRACE
The Grace stat.
void drawInfo(@NotNull final String message, final int color)
Pretends that a drawinfo message has been received.the message the color
Utility class for en-/decoding hexadecimal strings.
void connect(@NotNull final String hostname, final int port)
Attempts to connect the client to a server.the hostname to connect to the port to connect to ...
static final int DEFAULT_MAP_WIDTH
The default map width when no "setup mapsize" command has been sent.
void processStartingMapReplyinfo(@NotNull final ByteBuffer packet)
Processes a "replyinfo startingmap" block.
void mapDarkness(int x, int y, int darkness)
Part of "map2" parsing: change the darkness of a cell.
void connect(@NotNull final String hostname, final int port)
Attempts to connect the client to a server.the hostname to connect to the port to connect to ...
static final int CS_STAT_BASE_CHA
The charisma primary stat without boosts or depletions.
int COORD_LAYER0
Face information for layer 0.
void processDelItem(@NotNull final ByteBuffer packet)
Processes a 'delitem' server command.
static final byte [] ADDME_PREFIX
The command prefix for the "addme" command.
CONNECTED
Connection is fully established.
void processDrawInfo(@NotNull final ByteBuffer packet)
Processes a 'drawinfo' server command.
void fireEndAccountList(final int count)
static final int CS_STAT_APPLIED_WIS
The wisdom primary stat changes due to gear or skills.
static final int CS_STAT_ARMOUR
The Armour stat.
final String version
The version information to send when connecting to the server.
static final int ACL_NAME
Parameter type in the "accountplayers" command.
int sendNcom(final int repeat, @NotNull final String command)
Sends a "ncom" command to the server.the repeat count the command the packet id
void sendToggleextendedtext(@NotNull final int... types)
Sends a "toggleextendedtext" command to the server.the types to request