1: <?php
2:
3: namespace Budabot\Core;
4:
5: use Exception;
6:
7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46:
47:
48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62:
63:
64: 65: 66: 67: 68:
69: define('AOCP_LOGIN_SEED', 0);
70: define('AOCP_LOGIN_REQUEST', 2);
71: define('AOCP_LOGIN_SELECT', 3);
72: define('AOCP_LOGIN_OK', 5);
73: define('AOCP_LOGIN_ERROR', 6);
74: define('AOCP_LOGIN_CHARLIST', 7);
75: define('AOCP_CLIENT_UNKNOWN', 10);
76: define('AOCP_CLIENT_NAME', 20);
77: define('AOCP_CLIENT_LOOKUP', 21);
78: define('AOCP_MSG_PRIVATE', 30);
79: define('AOCP_MSG_VICINITY', 34);
80: define('AOCP_MSG_VICINITYA', 35);
81: define('AOCP_MSG_SYSTEM', 36);
82: define('AOCP_CHAT_NOTICE', 37);
83: define('AOCP_BUDDY_ADD', 40);
84: define('AOCP_BUDDY_REMOVE', 41);
85: define('AOCP_ONLINE_SET', 42);
86: define('AOCP_PRIVGRP_INVITE', 50);
87: define('AOCP_PRIVGRP_KICK', 51);
88: define('AOCP_PRIVGRP_JOIN', 52);
89: define('AOCP_PRIVGRP_PART', 53);
90: define('AOCP_PRIVGRP_KICKALL', 54);
91: define('AOCP_PRIVGRP_CLIJOIN', 55);
92: define('AOCP_PRIVGRP_CLIPART', 56);
93: define('AOCP_PRIVGRP_MESSAGE', 57);
94: define('AOCP_PRIVGRP_REFUSE', 58);
95: define('AOCP_GROUP_ANNOUNCE', 60);
96: define('AOCP_GROUP_PART', 61);
97: define('AOCP_GROUP_DATA_SET', 64);
98: define('AOCP_GROUP_MESSAGE', 65);
99: define('AOCP_GROUP_CM_SET', 66);
100: define('AOCP_CLIENTMODE_GET', 70);
101: define('AOCP_CLIENTMODE_SET', 71);
102: define('AOCP_PING', 100);
103: define('AOCP_FORWARD', 110);
104: define('AOCP_CC', 120);
105: define('AOCP_ADM_MUX_INFO', 1100);
106:
107: define('AOCP_GROUP_JOIN', AOCP_GROUP_ANNOUNCE);
108:
109: class AOChatPacket {
110: private static $packet_map = array(
111: "in" => array(
112: AOCP_LOGIN_SEED => array("name"=>"Login Seed", "args"=>"S"),
113: AOCP_LOGIN_OK => array("name"=>"Login Result OK", "args"=>""),
114: AOCP_LOGIN_ERROR => array("name"=>"Login Result Error", "args"=>"S"),
115: AOCP_LOGIN_CHARLIST => array("name"=>"Login CharacterList", "args"=>"isii"),
116: AOCP_CLIENT_UNKNOWN => array("name"=>"Client Unknown", "args"=>"I"),
117: AOCP_CLIENT_NAME => array("name"=>"Client Name", "args"=>"IS"),
118: AOCP_CLIENT_LOOKUP => array("name"=>"Lookup Result", "args"=>"IS"),
119: AOCP_MSG_PRIVATE => array("name"=>"Message Private", "args"=>"ISS"),
120: AOCP_MSG_VICINITY => array("name"=>"Message Vicinity", "args"=>"ISS"),
121: AOCP_MSG_VICINITYA => array("name"=>"Message Anon Vicinity", "args"=>"SSS"),
122: AOCP_MSG_SYSTEM => array("name"=>"Message System", "args"=>"S"),
123: AOCP_CHAT_NOTICE => array("name"=>"Chat Notice", "args"=>"IIIS"),
124: AOCP_BUDDY_ADD => array("name"=>"Buddy Added", "args"=>"IIS"),
125: AOCP_BUDDY_REMOVE => array("name"=>"Buddy Removed", "args"=>"I"),
126: AOCP_PRIVGRP_INVITE => array("name"=>"Privategroup Invited", "args"=>"I"),
127: AOCP_PRIVGRP_KICK => array("name"=>"Privategroup Kicked", "args"=>"I"),
128: AOCP_PRIVGRP_PART => array("name"=>"Privategroup Part", "args"=>"I"),
129: AOCP_PRIVGRP_CLIJOIN => array("name"=>"Privategroup Client Join", "args"=>"II"),
130: AOCP_PRIVGRP_CLIPART => array("name"=>"Privategroup Client Part", "args"=>"II"),
131: AOCP_PRIVGRP_MESSAGE => array("name"=>"Privategroup Message", "args"=>"IISS"),
132: AOCP_PRIVGRP_REFUSE => array("name"=>"Privategroup Refuse Invite", "args"=>"II"),
133: AOCP_GROUP_ANNOUNCE => array("name"=>"Group Announce", "args"=>"GSIS"),
134: AOCP_GROUP_PART => array("name"=>"Group Part", "args"=>"G"),
135: AOCP_GROUP_MESSAGE => array("name"=>"Group Message", "args"=>"GISS"),
136: AOCP_PING => array("name"=>"Pong", "args"=>"S"),
137: AOCP_FORWARD => array("name"=>"Forward", "args"=>"IM"),
138: AOCP_ADM_MUX_INFO => array("name"=>"Adm Mux Info", "args"=>"iii"),
139: ),
140: "out" => array(
141: AOCP_LOGIN_REQUEST => array("name"=>"Login Response GetCharLst", "args"=>"ISS"),
142: AOCP_LOGIN_SELECT => array("name"=>"Login Select Character", "args"=>"I"),
143: AOCP_CLIENT_LOOKUP => array("name"=>"Name Lookup", "args"=>"S"),
144: AOCP_MSG_PRIVATE => array("name"=>"Message Private", "args"=>"ISS"),
145: AOCP_BUDDY_ADD => array("name"=>"Buddy Add", "args"=>"IS"),
146: AOCP_BUDDY_REMOVE => array("name"=>"Buddy Remove", "args"=>"I"),
147: AOCP_ONLINE_SET => array("name"=>"Onlinestatus Set", "args"=>"I"),
148: AOCP_PRIVGRP_INVITE => array("name"=>"Privategroup Invite", "args"=>"I"),
149: AOCP_PRIVGRP_KICK => array("name"=>"Privategroup Kick", "args"=>"I"),
150: AOCP_PRIVGRP_JOIN => array("name"=>"Privategroup Join", "args"=>"I"),
151: AOCP_PRIVGRP_PART => array("name"=>"Privategroup Part", "args"=>"I"),
152: AOCP_PRIVGRP_KICKALL => array("name"=>"Privategroup Kickall", "args"=>""),
153: AOCP_PRIVGRP_MESSAGE => array("name"=>"Privategroup Message", "args"=>"ISS"),
154: AOCP_GROUP_DATA_SET => array("name"=>"Group Data Set", "args"=>"GIS"),
155: AOCP_GROUP_MESSAGE => array("name"=>"Group Message", "args"=>"GSS"),
156: AOCP_GROUP_CM_SET => array("name"=>"Group Clientmode Set", "args"=>"GIIII"),
157: AOCP_CLIENTMODE_GET => array("name"=>"Clientmode Get", "args"=>"IG"),
158: AOCP_CLIENTMODE_SET => array("name"=>"Clientmode Set", "args"=>"IIII"),
159: AOCP_PING => array("name"=>"Ping", "args"=>"S"),
160: AOCP_CC => array("name"=>"CC", "args"=>"s"),
161: )
162: );
163:
164: function __construct($dir, $type, $data) {
165: $this->args = array();
166: $this->type = $type;
167: $this->dir = $dir;
168: $pmap = self::$packet_map[$dir][$type];
169:
170: if (!$pmap) {
171: throw new Exception("Unsupported packet type (". $dir . ", " . $type . ")");
172: return false;
173: }
174:
175: if ($dir == "in") {
176: if (!is_string($data)) {
177: throw new Exception("Incorrect argument for incoming packet, expecting a string.");
178: return false;
179: }
180:
181: for ($i = 0; $i < strlen($pmap["args"]); $i++) {
182: $sa = $pmap["args"][$i];
183: switch ($sa) {
184: case "I":
185: $res = array_pop(unpack("N", $data));
186: $data = substr($data, 4);
187: break;
188:
189: case "S":
190: $len = array_pop(unpack("n", $data));
191: $res = substr($data, 2, $len);
192: $data = substr($data, 2 + $len);
193: break;
194:
195: case "G":
196: $res = substr($data, 0, 5);
197: $data = substr($data, 5);
198: break;
199:
200: case "i":
201: $len = array_pop(unpack("n", $data));
202: $res = array_values(unpack("N" . $len, substr($data, 2)));
203: $data = substr($data, 2 + 4 * $len);
204: break;
205:
206: case "s":
207: $len = array_pop(unpack("n", $data));
208: $data = substr($data, 2);
209: $res = array();
210: while ($len--) {
211: $slen = array_pop(unpack("n", $data));
212: $res[] = substr($data, 2, $slen);
213: $data = substr($data, 2+$slen);
214: }
215: break;
216:
217: default:
218: throw new Exception("Unknown argument type! (" . $sa . ")");
219: continue(2);
220: }
221: $this->args[] = $res;
222: }
223: } else {
224: if (!is_array($data)) {
225: $args = array($data);
226: } else {
227: $args = $data;
228: }
229: $data = "";
230:
231: for ($i = 0; $i < strlen($pmap["args"]); $i++) {
232: $sa = $pmap["args"][$i];
233: $it = array_shift($args);
234:
235: if (is_null($it)) {
236: throw new Exception("Missing argument for packet.");
237: break;
238: }
239:
240: switch ($sa) {
241: case "I":
242: $data .= pack("N", $it);
243: break;
244:
245: case "S":
246: $data .= pack("n", strlen($it)) . $it;
247: break;
248:
249: case "G":
250: $data .= $it;
251: break;
252:
253: case "s":
254: $data .= pack("n", count($it));
255: forEach ($it as $it_elem) {
256: $data .= pack("n", strlen($it_elem)) . $it_elem;
257: }
258: break;
259:
260: default:
261: throw new Exception("Unknown argument type! (" . $sa . ")");
262: continue(2);
263: }
264: }
265:
266: $this->data = $data;
267: }
268: return true;
269: }
270: }
271: