-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1540807
commit c36d777
Showing
9 changed files
with
287 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { HDirection } from "../../../protocol/hdirection"; | ||
import { HPacket } from "../../../protocol/hpacket"; | ||
|
||
export class AwaitingPacket { | ||
constructor(headerName: string, direction: HDirection, maxWaitingTimeMillis: number); | ||
|
||
/** | ||
* Set minimum waiting time (wait this time even if the packet was already intercepted) | ||
* @param millis minimum waiting time | ||
*/ | ||
setMinWaitingTime(millis: number): AwaitingPacket; | ||
|
||
/** | ||
* Add a condition to the awaiting packet | ||
* @param condition Predicate with HPacket parameter return true or false | ||
*/ | ||
addCondition(condition: (hPacket: HPacket) => boolean): AwaitingPacket; | ||
|
||
/** | ||
* Get header name of awaiting packet | ||
*/ | ||
get headerName(): string; | ||
|
||
/** | ||
* Get direction of awaiting packet | ||
*/ | ||
get direction(): HDirection; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
const {HDirection} = require("../../../protocol/hdirection"); | ||
const {HPacket} = require("../../../protocol/hpacket"); | ||
const {HMessage} = require("../../../protocol/hmessage"); | ||
exports.AwaitingPacket = class AwaitingPacket { | ||
#headerName; | ||
#direction; | ||
#packet; | ||
#received = false; | ||
#conditions = []; | ||
#start; | ||
#minWait = 0; | ||
|
||
constructor(headerName, direction, maxWaitingTimeMillis) { | ||
if (typeof headerName !== 'string') { | ||
throw new Error("AwaitingPacket.constructor: headerName must be a string"); | ||
} | ||
if (!HDirection.identify(direction)) { | ||
throw new Error("AwaitingPacket.constructor: direction must be a value of HDirection"); | ||
} | ||
if (!Number.isInteger(maxWaitingTimeMillis)) { | ||
throw new Error("AwaitingPacket.constructor: maxWaitingTimeMillis must be an integer"); | ||
} | ||
|
||
if(maxWaitingTimeMillis < 30) { | ||
maxWaitingTimeMillis = 30; | ||
} | ||
|
||
setTimeout(() => { | ||
this.#received = true; | ||
}, maxWaitingTimeMillis); | ||
|
||
this.#start = Date.now(); | ||
|
||
this.#direction = direction; | ||
this.#headerName = headerName; | ||
} | ||
|
||
get headerName() { | ||
return this.#headerName; | ||
} | ||
|
||
get direction() { | ||
return this.#direction; | ||
} | ||
|
||
setMinWaitingTime(millis) { | ||
if (!Number.isInteger(millis)) { | ||
throw new Error("AwaitingPacket.setMinWaitingTime: millis must be an integer"); | ||
} | ||
|
||
this.minWait = millis; | ||
|
||
return this; | ||
} | ||
|
||
addCondition(condition) { | ||
if (typeof condition !== 'function') { | ||
throw new Error("AwaitingPacket.addCondition: condition must be a function"); | ||
} | ||
|
||
this.#conditions.push(condition); | ||
|
||
return this; | ||
} | ||
|
||
set packet(val) { | ||
if (!(val instanceof HPacket)) { | ||
throw new Error("AwaitingPacket.setPacket: packet must be an instance of HPacket") | ||
} | ||
|
||
this.#packet = val; | ||
this.#received = true; | ||
} | ||
|
||
get packet() { | ||
if (this.#packet !== undefined) { | ||
this.#packet.resetReadIndex(); | ||
} | ||
|
||
return this.#packet; | ||
} | ||
|
||
test(hMessage) { | ||
if (!(hMessage instanceof HMessage)) { | ||
throw new Error("AwaitingPacket.test: hMessage must be an instance of HMessage"); | ||
} | ||
|
||
for (let condition of this.#conditions) { | ||
let packet = hMessage.getPacket(); | ||
packet.resetReadIndex(); | ||
if(!condition(packet)) { | ||
return false; | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|
||
get ready() { | ||
return this.#received && (this.#start + this.#minWait) < Date.now(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { Extension } from "../../extension"; | ||
import { AwaitingPacket } from "./awaitingpacket"; | ||
import { HPacket } from "../../../protocol/hpacket"; | ||
|
||
|
||
export class GAsync { | ||
constructor(ext: Extension); | ||
|
||
/** | ||
* Asynchronously await a packet | ||
* @param packets | ||
*/ | ||
awaitPacket(...packets: AwaitingPacket[]): HPacket | undefined; | ||
|
||
/** | ||
* Asynchronously await multiple packets | ||
* @param packets | ||
*/ | ||
awaitMultiplePackets(...packets: AwaitingPacket[]): (HPacket | undefined)[]; | ||
|
||
/** | ||
* Clear all awaiting packets | ||
*/ | ||
clear(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
const { Extension } = require("../../extension"); | ||
const { HDirection } = require("../../../protocol/hdirection"); | ||
const { AwaitingPacket } = require("./awaitingpacket"); | ||
|
||
exports.GAsync = class GAsync { | ||
#packetInfoManager = undefined; | ||
#awaitingPackets = []; | ||
|
||
constructor(ext) { | ||
if (!(ext instanceof Extension)) { | ||
throw new Error("GAsync.constructor: ext must be an instance of Extension"); | ||
} | ||
this.#packetInfoManager = ext.getPacketInfoManager(); | ||
ext.on('start', () => { | ||
this.#packetInfoManager = ext.getPacketInfoManager(); | ||
}); | ||
|
||
ext.interceptAll(HDirection.TOSERVER, this.#onMessageToServer.bind(this)); | ||
ext.interceptAll(HDirection.TOCLIENT, this.#onMessageToClient.bind(this)); | ||
} | ||
|
||
#onMessageToServer(hMessage) { | ||
if (this.#packetInfoManager !== undefined) { | ||
let info = this.#packetInfoManager.getPacketInfoFromHeaderId(HDirection.TOSERVER, hMessage.getPacket().headerId()); | ||
if(info === null) { | ||
return; | ||
} | ||
|
||
this.#awaitingPackets | ||
.filter(p => p.direction === HDirection.TOSERVER) | ||
.filter(p => p.headerName === info.name) | ||
.filter(p => p.test(hMessage)) | ||
.forEach(p => p.packet = hMessage.getPacket()); | ||
} | ||
} | ||
|
||
#onMessageToClient(hMessage) { | ||
if(this.#packetInfoManager !== undefined) { | ||
let info = this.#packetInfoManager.getPacketInfoFromHeaderId(HDirection.TOCLIENT, hMessage.getPacket().headerId()); | ||
if(info === null) { | ||
return; | ||
} | ||
|
||
this.#awaitingPackets | ||
.filter(p => p.direction === HDirection.TOCLIENT) | ||
.filter(p => p.headerName === info.name) | ||
.filter(p => p.test(hMessage)) | ||
.forEach(p => p.packet = hMessage.getPacket()); | ||
} | ||
} | ||
|
||
async awaitPacket(...packets) { | ||
for (let packet of packets) { | ||
if (!(packet instanceof AwaitingPacket)) { | ||
throw new Error("GAsync.awaitMultiplePackets: all packets must be an instance of AwaitingPacket"); | ||
} | ||
} | ||
|
||
this.#awaitingPackets.push(...packets); | ||
|
||
return new Promise(resolve => { | ||
let interval = setInterval(() => { | ||
for (let packet of packets.filter(p => p.ready)) { | ||
clearInterval(interval); | ||
this.#awaitingPackets = this.#awaitingPackets.filter(p => !packets.includes(p)); | ||
resolve(packet.packet); | ||
} | ||
}, 1); | ||
}); | ||
} | ||
|
||
async awaitMultiplePackets(...packets) { | ||
for(let packet of packets) { | ||
if(!(packet instanceof AwaitingPacket)) { | ||
throw new Error("GAsync.awaitMultiplePackets: all packets must be an instance of AwaitingPacket"); | ||
} | ||
} | ||
|
||
this.#awaitingPackets.push(...packets); | ||
|
||
return new Promise(resolve => { | ||
let interval = setInterval(() => { | ||
if(!packets.map(p => p.ready).includes(false)) { | ||
clearInterval(interval); | ||
this.#awaitingPackets = this.#awaitingPackets.filter(p => !packets.includes(p)); | ||
resolve(packets.map(p => p.packet)); | ||
} | ||
}, 1); | ||
}); | ||
} | ||
|
||
clear() { | ||
this.#awaitingPackets = []; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,31 @@ | ||
const { Extension, HDirection, HEntity, HUserProfile} = require('../index'); | ||
const { Extension, HDirection, HEntity, HEntityUpdate} = require('../index'); | ||
|
||
const extensionInfo = require('./package.json'); | ||
const { GAsync } = require("../lib/extension/tools/gasync/gasync"); | ||
const {AwaitingPacket} = require("../lib/extension/tools/gasync/awaitingpacket"); | ||
|
||
const ext = new Extension(extensionInfo); | ||
//ext.run(); | ||
const gAsync = new GAsync(ext); | ||
ext.run(); | ||
|
||
ext.interceptByNameOrHash(HDirection.TOCLIENT, 'Users', onUsers); | ||
|
||
ext.interceptByNameOrHash(HDirection.TOCLIENT, 'ExtendedProfile', onExtendedProfile) | ||
ext.interceptByNameOrHash(HDirection.TOSERVER, "MoveAvatar", async hMessage => { | ||
let packet = hMessage.getPacket(); | ||
let x = packet.readInteger(); | ||
let y = packet.readInteger(); | ||
|
||
function onUsers(hMessage) { | ||
let users = HEntity.parse(hMessage.getPacket()); | ||
hMessage.blocked = true; | ||
for(let user of users) { | ||
user.figureId = "hr-828-49.hd-180-28.ch-3788-92.lg-3136-106.sh-290-92.ea-3803-92.ca-3187-92"; | ||
} | ||
let awaitedPacket = await gAsync | ||
.awaitPacket(new AwaitingPacket("UserUpdate", HDirection.TOCLIENT, 1000) | ||
.addCondition(hPacket => { | ||
let entityUpdates = HEntityUpdate.parse(hPacket); | ||
for (let entityUpdate of entityUpdates) { | ||
if(entityUpdate.tile.x === x && entityUpdate.tile.y === y) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
}) | ||
); | ||
|
||
let packet = HEntity.constructPacket(users, hMessage.getPacket().headerId()); | ||
ext.sendToClient(packet); | ||
} | ||
|
||
function onExtendedProfile(hMessage) { | ||
console.log(hMessage); | ||
} | ||
console.log(awaitedPacket); | ||
}); |