1 package net.sourceforge.queried.gametypes;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5
6 import net.sourceforge.queried.PlayerInfo;
7 import net.sourceforge.queried.QueriEd;
8 import net.sourceforge.queried.ScoreComparator;
9 import net.sourceforge.queried.ServerInfo;
10 import net.sourceforge.queried.Util;
11
12
13
14
15
16
17 public class UT2ServerInfo {
18
19
20
21
22
23
24
25
26 private static int getInt(String str, int[] offsetHolder) {
27 int v =
28 ((str.charAt(offsetHolder[0] + 0) & 255) << 0) |
29 ((str.charAt(offsetHolder[0] + 1) & 255) << 8) |
30 ((str.charAt(offsetHolder[0] + 2) & 255) << 16) |
31 ((str.charAt(offsetHolder[0] + 3) & 255) << 24);
32
33 offsetHolder[0] += 4;
34 return v;
35 }
36
37
38
39
40
41
42
43
44 private static String getString(String src, int[] offsetHolder) {
45 int len = src.charAt(offsetHolder[0]++);
46 if(len == 0 || len == 128) {
47 return "";
48
49 } else if(len > 0 && len <= 127) {
50 String result = src.substring(offsetHolder[0], offsetHolder[0] + len - 1);
51 offsetHolder[0] += len;
52 return result;
53
54 } else if(len > 128 && len <= 255) {
55 len -= 128;
56 StringBuffer sb = new StringBuffer();
57 for(int i=0; i<len-1; i++) {
58 char ch = src.charAt(offsetHolder[0] + i*2);
59 if(ch == '^' && src.charAt(offsetHolder[0] + i*2 + 2) == '#') {
60
61 i += 2;
62 } else {
63 sb.append(ch);
64 }
65 }
66 offsetHolder[0] += len * 2;
67 return sb.toString();
68
69 } else {
70 throw new RuntimeException("Bad data in response");
71 }
72 }
73
74 public static ServerInfo getDetails(int localPort, String ipStr, int port, int infoType, int queryType,
75 int gameType) {
76
77 if(queryType != QueriEd.QUERY_UT2S) {
78
79 return UTServerInfo.getDetails(localPort, ipStr, port, infoType, queryType, gameType);
80 }
81
82 String queryResult =
83 Util.getInfo(localPort, ipStr, port, "\u0078\u0000\u0000\u0000\u0000", infoType, queryType, gameType);
84
85 if(queryResult == null || queryResult.length() == 0) return null;
86
87 ServerInfo serverInfo = new ServerInfo();
88 try {
89
90 int[] offsetHolder = { 0 };
91 if(queryResult.charAt(0) == 128) offsetHolder[0] = 4;
92 if(queryResult.charAt(offsetHolder[0]) != 0) return null;
93 offsetHolder[0]++;
94
95 serverInfo.setIp(ipStr);
96
97 getInt(queryResult, offsetHolder);
98 getString(queryResult, offsetHolder);
99 serverInfo.setPort(Integer.toString(getInt(queryResult, offsetHolder)));
100 getInt(queryResult, offsetHolder);
101 serverInfo.setName(getString(queryResult, offsetHolder));
102 serverInfo.setMap(getString(queryResult, offsetHolder));
103 serverInfo.setGame(getString(queryResult, offsetHolder));
104 serverInfo.setPlayerCount(Integer.toString(getInt(queryResult, offsetHolder)));
105 serverInfo.setMaxPlayers(Integer.toString(getInt(queryResult, offsetHolder)));
106 getInt(queryResult, offsetHolder);
107 serverInfo.setFullResponse(queryResult);
108
109 } catch(StringIndexOutOfBoundsException e) {
110 return null;
111 }
112
113
114
115
116 queryResult =
117 Util.getInfo(localPort, ipStr, port, "\u0078\u0000\u0000\u0000\u0001", infoType, queryType, gameType);
118
119 if(queryResult == null || queryResult.length() == 0) return serverInfo;
120
121 try {
122
123 int[] offsetHolder = { 0 };
124 if(queryResult.charAt(0) == 128) offsetHolder[0] = 4;
125 if(queryResult.charAt(offsetHolder[0]) == 1) {
126 offsetHolder[0]++;
127
128
129 while(offsetHolder[0] < queryResult.length()) {
130 String key = getString(queryResult, offsetHolder);
131 String value = getString(queryResult, offsetHolder);
132 if(key.equals("ServerVersion")) {
133 serverInfo.setGameVersion(value);
134 break;
135 }
136 }
137 }
138
139 } catch(StringIndexOutOfBoundsException e) {
140
141 }
142
143 return serverInfo;
144 }
145
146 public static ArrayList getPlayers(int localPort, String ipStr, int port, int infoType, int queryType,
147 int gameType) {
148
149 if(queryType != QueriEd.QUERY_UT2S) {
150
151 return UTServerInfo.getPlayers(localPort, ipStr, port, infoType, queryType, gameType);
152 }
153
154 String queryResult =
155 Util.getInfo(localPort, ipStr, port, "\u0078\u0000\u0000\u0000\u0002", infoType, queryType, gameType);
156
157 if(queryResult == null || queryResult.length() == 0) return null;
158
159 ArrayList playerInfo = new ArrayList();
160 try {
161
162 int[] offsetHolder = { 0 };
163 if(queryResult.charAt(0) == 128) offsetHolder[0] = 4;
164 if(queryResult.charAt(offsetHolder[0]) != 2) return null;
165 offsetHolder[0]++;
166
167
168 while(offsetHolder[0] < queryResult.length()) {
169 PlayerInfo player = new PlayerInfo();
170
171 getInt(queryResult, offsetHolder);
172 player.setName(getString(queryResult, offsetHolder));
173 getInt(queryResult, offsetHolder);
174 player.setScore(getInt(queryResult, offsetHolder));
175 getInt(queryResult, offsetHolder);
176
177 playerInfo.add(player);
178 }
179 } catch(StringIndexOutOfBoundsException e) {
180 return null;
181 }
182
183 Collections.sort(playerInfo, new ScoreComparator());
184 return playerInfo;
185 }
186 }