Skip to content

Commit 2a1206b

Browse files
author
RaizeTheLimit
committed
feat(mobile-ui): add responsive design, add ability to quick copy proto message data
1 parent 2316596 commit 2a1206b

5 files changed

Lines changed: 319 additions & 60 deletions

File tree

src/parser/proto-parser.ts

Lines changed: 66 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,22 @@ import { b64Decode } from "../utils";
22
import { requestMessagesResponses } from "../constants";
33
import { DecodedProto } from "../types";
44

5-
// For decode dynamics action social.
65
let action_social = 0;
7-
/**
8-
* Callback as used by {@link DecoderInternalPayloadAsResponse}.
9-
* @type {function}
10-
* @param {number|any}
11-
*/
12-
/**
13-
* Returns decoded proto as JSON. Uses Tuples by https://github.com/Furtif/pogo-protos/blob/master/test/test.js, if that implemented.
14-
*/
156
function DecoderInternalPayloadAsResponse(method: number, data: any): any {
16-
// Reset value.
177
action_social = 0;
188
let proto_tuple: any = Object.values(requestMessagesResponses)[method];
199
let result: any = { Not_Implemented_yet: data };
10+
11+
if (!data) {
12+
return {};
13+
}
2014
for (let i = 0; i < Object.keys(requestMessagesResponses).length; i++) {
2115
proto_tuple = Object.values(requestMessagesResponses)[i];
2216
const my_req = proto_tuple[0];
2317
if (my_req == method) {
24-
if (proto_tuple[2] != null && b64Decode(data)) {
18+
if (proto_tuple[2] != null && data && b64Decode(data).length > 0) {
2519
try {
2620
result = proto_tuple[2].decode(b64Decode(data)).toJSON();
27-
/*
28-
// This not need more because protos as replaced bytes for the proto.
29-
if (method == 10010) {
30-
let profile = POGOProtos.Rpc.PlayerPublicProfileProto.decode(b64Decode(result.friend[0].player.public_data)).toJSON();
31-
result.friend[0].player.public_data = profile;
32-
}
33-
*/
3421
}
3522
catch (error) {
3623
console.error(`Intenal ProxySocial decoder ${my_req} Error: ${error}`);
@@ -85,14 +72,22 @@ export const decodePayload = (contents: any, dataType: string): DecodedProto[] =
8572

8673
export const decodeProto = (method: number, data: string, dataType: string): DecodedProto | string => {
8774
let returnObject: DecodedProto | string = "Not Found";
75+
let methodFound = false;
76+
8877
for (let i = 0; i < Object.keys(requestMessagesResponses).length; i++) {
8978
let foundMethod: any = Object.values(requestMessagesResponses)[i];
9079
let foundMethodString: string = Object.keys(requestMessagesResponses)[i];
9180
const foundReq = foundMethod[0];
9281
if (foundReq == method) {
82+
methodFound = true;
9383
if (foundMethod[1] != null && dataType === "request") {
9484
try {
95-
let parsedData = foundMethod[1].decode(b64Decode(data)).toJSON();
85+
let parsedData;
86+
if (!data || data === "") {
87+
parsedData = {};
88+
} else {
89+
parsedData = foundMethod[1].decode(b64Decode(data)).toJSON();
90+
}
9691
if (foundMethod[0] === 5012 || foundMethod[0] === 600005) {
9792
action_social = parsedData.action;
9893
Object.values(requestMessagesResponses).forEach(val => {
@@ -109,13 +104,35 @@ export const decodeProto = (method: number, data: string, dataType: string): Dec
109104
};
110105
} catch (error) {
111106
console.error(`Error parsing request ${foundMethodString} -> ${error}`);
107+
returnObject = {
108+
methodId: foundMethod[0],
109+
methodName: remasterOrCleanMethodString(foundMethodString) + " [PARSE ERROR]",
110+
data: {
111+
error: "Failed to decode proto",
112+
rawBase64: data,
113+
errorMessage: error.toString()
114+
},
115+
};
112116
}
113117
} else if (dataType === "request") {
114118
console.warn(`Request ${foundMethod[0]} Not Implemented`)
119+
returnObject = {
120+
methodId: foundMethod[0],
121+
methodName: remasterOrCleanMethodString(foundMethodString) + " [NOT IMPLEMENTED]",
122+
data: {
123+
error: "Proto not implemented",
124+
rawBase64: data
125+
},
126+
};
115127
}
116128
if (foundMethod[2] != null && dataType === "response") {
117129
try {
118-
let parsedData = foundMethod[2].decode(b64Decode(data)).toJSON();
130+
let parsedData;
131+
if (!data || data === "") {
132+
parsedData = {};
133+
} else {
134+
parsedData = foundMethod[2].decode(b64Decode(data)).toJSON();
135+
}
119136
if (foundMethod[0] === 5012 && action_social > 0 && parsedData.payload) {
120137
parsedData.payload = DecoderInternalPayloadAsResponse(action_social, parsedData.payload);
121138
}
@@ -129,11 +146,40 @@ export const decodeProto = (method: number, data: string, dataType: string): Dec
129146
};
130147
} catch (error) {
131148
console.error(`Error parsing response ${foundMethodString} method: [${foundReq}] -> ${error}`);
149+
returnObject = {
150+
methodId: foundMethod[0],
151+
methodName: remasterOrCleanMethodString(foundMethodString) + " [PARSE ERROR]",
152+
data: {
153+
error: "Failed to decode proto",
154+
rawBase64: data,
155+
errorMessage: error.toString()
156+
},
157+
};
132158
}
133159
} else if (dataType === "response") {
134160
console.warn(`Response ${foundReq} Not Implemented`)
161+
returnObject = {
162+
methodId: foundMethod[0],
163+
methodName: remasterOrCleanMethodString(foundMethodString) + " [NOT IMPLEMENTED]",
164+
data: {
165+
error: "Proto not implemented",
166+
rawBase64: data
167+
},
168+
};
135169
}
136170
}
137171
}
172+
173+
if (!methodFound && returnObject === "Not Found") {
174+
returnObject = {
175+
methodId: method.toString(),
176+
methodName: `Unknown Method ${method} [UNKNOWN]`,
177+
data: {
178+
error: "Unknown method ID",
179+
rawBase64: data
180+
},
181+
};
182+
}
183+
138184
return returnObject;
139185
};

src/types/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ export type DecodedProto = {
22
identifier?: string;
33
methodId: string;
44
methodName: string;
5-
data: string;
5+
data: any;
66
};

src/utils/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import { WebStreamBuffer } from "./web-stream-buffer";
55
import { decodePayloadTraffic } from "../parser/proto-parser";
66

77
export const b64Decode = (data: string) => {
8+
if (!data || data === "") {
9+
return Buffer.alloc(0);
10+
}
811
return Buffer.from(data, "base64");
912
};
1013

src/views/css/style.css

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,116 @@ table tr td.important {
118118
text-align: right;
119119
border-top: 2px solid rgba(255, 255, 255, 0.5);
120120
width: 100%;
121+
}
122+
123+
/* Mobile styles - hide by default */
124+
.mobile-only {
125+
display: none !important;
126+
}
127+
128+
.text-center {
129+
text-align: center;
130+
}
131+
132+
.clickable-data:hover {
133+
background-color: rgba(0, 123, 255, 0.05) !important;
134+
border: 1px solid rgba(0, 123, 255, 0.2);
135+
transition: all 0.2s ease;
136+
}
137+
138+
.dark .clickable-data:hover {
139+
background-color: rgba(0, 123, 255, 0.1) !important;
140+
border: 1px solid rgba(0, 123, 255, 0.3);
141+
}
142+
143+
/* Mobile breakpoint */
144+
@media (max-width: 768px) {
145+
.mobile-hide {
146+
display: none !important;
147+
}
148+
149+
.mobile-only {
150+
display: table-cell !important;
151+
}
152+
153+
/* Optimize table for mobile */
154+
#data_socket {
155+
font-size: smaller;
156+
}
157+
158+
#data_socket th,
159+
#data_socket td {
160+
padding: 4px !important;
161+
font-size: 11px;
162+
}
163+
164+
/* Make method name wrap on mobile */
165+
#data_socket td:nth-child(3) {
166+
word-break: break-word;
167+
max-width: 120px;
168+
}
169+
170+
/* Filters optimization for mobile */
171+
.col-sm-10, .col-sm-2 {
172+
padding: 5px !important;
173+
}
174+
175+
#filter-mode, #instance-filter-dropdown, #maxlogs {
176+
width: 100% !important;
177+
margin-bottom: 5px;
178+
}
179+
180+
#method-filter-ids {
181+
width: 100% !important;
182+
margin-top: 5px;
183+
}
184+
185+
label {
186+
display: block !important;
187+
width: 100% !important;
188+
margin-bottom: 3px;
189+
}
190+
191+
/* Card header for mobile */
192+
.card-header .title-proto {
193+
font-size: 16px !important;
194+
}
195+
196+
.card-header .icons i {
197+
font-size: 12px !important;
198+
margin-right: 8px !important;
199+
}
200+
201+
/* Footer for mobile */
202+
.footer {
203+
font-size: 10px;
204+
padding: 5px;
205+
}
206+
207+
/* Modal optimization for mobile */
208+
.modal-dialog {
209+
max-width: 95% !important;
210+
margin: 10px auto !important;
211+
}
212+
213+
.modal-content {
214+
margin: 0 auto;
215+
}
216+
217+
.modal-body {
218+
padding: 10px !important;
219+
max-height: 70vh;
220+
overflow-y: auto;
221+
}
222+
223+
.modal-footer {
224+
padding: 10px !important;
225+
flex-wrap: wrap;
226+
}
227+
228+
.modal-footer button {
229+
margin: 3px !important;
230+
font-size: 12px !important;
231+
padding: 5px 10px !important;
232+
}
121233
}

0 commit comments

Comments
 (0)