-
Notifications
You must be signed in to change notification settings - Fork 44
/
Copy pathCachedBuffer.js
173 lines (172 loc) · 8.38 KB
/
CachedBuffer.js
1
2
3
4
5
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
// This file is part of InfiniteSky.
// Copyright (c) InfiniteSky Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
// Need to setup testing :).
var hexy = require('hexy').hexy;
var util = require('./util');
// function logHex(data) {
// if (data===null || data.length==0) return;
// console.log("\n");
// console.log(data);
// var testSplit = data.toString("hex");
// console.log(testSplit);
// testSplit = testSplit.match(/../g);
// console.log(testSplit);
// var lineVal = "";
// var asciiVal = "";
// var hexCounter = 0;
// var c = "";
// for(var i = 0; i < testSplit.length; i++) {
// lineVal += testSplit[i] + " ";
// c = String.fromCharCode(data[i]);
// asciiVal += c;
// hexCounter++;
// if(hexCounter == 15) {
// console.log(lineVal + ' - ' + asciiVal);
// lineVal = "";
// hexCounter = 0;
// }
// }
// }
// Should add in a way to test different packet id's.
var CachedBuffer = function(packet_collection, options) {
this.BufferSize = 10240;
this.HeaderSize = 9;
this.PacketIDPos = 8;
this.data = new Buffer(this.BufferSize); // 1MB Buffer Size ought to be enough?
this.bufferLength = 0;
this.badCount = 0;
this.badLimit = 0;
var onDataInProgress = false;
if(options) {
this.BufferSize = options.BufferSize;
this.HeaderSize = options.HeaderSize;
this.PacketIDPos = options.PacketIDPos;
this.badLimit = options.badLimit;
}
// PacketIDPos should not be > HeaderSize
this.onData = function(newData) {
if(newData === null) return;
var position = 0;
if(this.bufferLength + newData.length > this.BufferSize) {
throw('Data to large for buffer');
return;
}
newData.copy(this.data, this.bufferLength);
this.bufferLength += newData.length;
if(onDataInProgress) return;
onDataInProgress = true;
var packet;
do {
packet = null;
if(this.bufferLength - position >= this.HeaderSize) // If has enough space for header and packet id
{
// Could read header here if we cared.
var PositionBeforePacketID = position;
var packetID = this.data.readUInt8(position + this.PacketIDPos);
//console.log('Position: '+position+' IDPos: '+ (position + this.PacketIDPos));
//console.log('DATA HEADER RECV: ',this.data.slice(position,position+10));
position += this.HeaderSize;
packet = packet_collection.Get(packetID);
if(packet != null) {
if (this.debug) {
if(packetID === packet_collection.LastAdded) {
console.log('\x1b[31;5m---------------- Last Added Packet ----------------\x1b[0m');
}
console.log('PacketID: 0x' + _util.padLeft(packetID.toString(16).toUpperCase(),'0',2) + ' bufsize: ' + (this.bufferLength - position) + ' ' + packet.
function.name);
}
//console.log('PacketFunction: '+packet.function.name);
if(!packet.Restruct) { // Check if not a restruct packet
// Check if not a packet with data, for example this packet would only have a header/ID no data.
if(!packet.Size || packet.Size == 0) {
try {
packet.
function(this, packetID);
} catch(ex) {
// For testing only...
this.bufferLength = 0;
dumpError(ex)
}
this.badCount = 0;
} else if(packet.Size && this.bufferLength - position >= packet.Size) { // Check for a packet with Size
if(this.debug) {
console.log('PacketSize: ' + packet.Size);
}
try {
packet.
function(this, this.data.slice(position, position + packet.Size), packetID);
} catch(ex) {
// For testing only...
this.bufferLength = 0;
dumpError(ex)
}
position += packet.Size;
this.badCount = 0;
} else { // No check matched, maybe not enough data or bad packet definition?
packet = null;
}
} else if(packet.Restruct && this.bufferLength - position >= packet.Restruct.size) {
// Read the data for the packet and pass it into the function
if(this.debug) {
console.log('PacketSize: ' + packet.Restruct.size);
}
try {
// We need a buffer to be passed to final function to be able to restruct that in separated way cause to guild handler method changes input
packet.
function(this, packet.Restruct.unpack(this.data.slice(position, position + packet.Restruct.size)), packetID);
} catch(ex) {
// For testing only...
this.bufferLength = 0;
dumpError(ex)
}
position += packet.Restruct.size;
this.badCount = 0;
} else {
packet = null;
}
} else {
// unreconized packet id
if(this.onUnrecognizedPacket) this.onUnrecognizedPacket(packetID);
console.log('Unreconized PacketID: 0x' + _util.padLeft(packetID.toString(16).toUpperCase(),'0',2) + ' Size: ' + (this.bufferLength - position));
//logHex(this.data.slice(position,this.bufferLength));
console.log(hexy(this.data.slice(position, this.bufferLength)));
// For testing only this will reset buffer to empty.
// Which may have packet data loss but meh
this.bufferLength = 0;
// Output to log file or something?
// Throw away buffer data
//this.bufferLength = 0;
//position = 0;
this.badCount++;
}
if(packet === null) {
position = PositionBeforePacketID;
this.badCount++;
}
if(this.badLimit && this.badCount >= this.badLimit) {
if(this.onBadfunction) this.onBadfunction();
}
}
// If socket is closed now
if(!this._handle) break;
// break;
}
while (packet != null);
onDataInProgress = false;
// If there is data left over here then it would be waiting for more data.
// we should do some sort of check to make sure more data comes and that it is valid.
if(this.bufferLength - position > 0) {
this.data.copy(this.data, 0, this.bufferLength - position, this.bufferLength);
this.bufferLength = this.bufferLength - position;
} else {
// Reset to beginning of buffer to store data at
this.bufferLength = 0;
}
if(this.afterPacketsHandled) this.afterPacketsHandled();
};
this.on('data', function(newData) {
this.onData(newData);
});
}
module.exports = CachedBuffer;