the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
1#include "stdafx.h"
2#include "Class.h"
3#include "BasicTypeContainers.h"
4#include "InputOutputStream.h"
5#include "net.minecraft.h"
6#include "net.minecraft.network.packet.h"
7#include "net.minecraft.world.item.h"
8#include "SynchedEntityData.h"
9
10
11SynchedEntityData::SynchedEntityData()
12{
13 m_isDirty = false;
14 m_isEmpty = true;
15}
16
17void SynchedEntityData::define(int id, int value)
18{
19 MemSect(17);
20 checkId(id);
21 int type = TYPE_INT;
22 shared_ptr<DataItem> dataItem = shared_ptr<DataItem>( new DataItem(type, id, value) );
23 itemsById[id] = dataItem;
24 MemSect(0);
25 m_isEmpty = false;
26}
27
28void SynchedEntityData::define(int id, byte value)
29{
30 MemSect(17);
31 checkId(id);
32 int type = TYPE_BYTE;
33 shared_ptr<DataItem> dataItem = shared_ptr<DataItem>( new DataItem(type, id, value) );
34 itemsById[id] = dataItem;
35 MemSect(0);
36 m_isEmpty = false;
37}
38
39void SynchedEntityData::define(int id, short value)
40{
41 MemSect(17);
42 checkId(id);
43 int type = TYPE_SHORT;
44 shared_ptr<DataItem> dataItem = shared_ptr<DataItem>( new DataItem(type, id, value) );
45 itemsById[id] = dataItem;
46 MemSect(0);
47 m_isEmpty = false;
48}
49
50void SynchedEntityData::define(int id, float value)
51{
52 MemSect(17);
53 checkId(id);
54 int type = TYPE_FLOAT;
55 shared_ptr<DataItem> dataItem = shared_ptr<DataItem>( new DataItem(type, id, value) );
56 itemsById[id] = dataItem;
57 MemSect(0);
58 m_isEmpty = false;
59}
60
61void SynchedEntityData::define(int id, const wstring& value)
62{
63 MemSect(17);
64 checkId(id);
65 int type = TYPE_STRING;
66 shared_ptr<DataItem> dataItem = shared_ptr<DataItem>( new DataItem(type, id, value) );
67 itemsById[id] = dataItem;
68 MemSect(0);
69 m_isEmpty = false;
70}
71
72void SynchedEntityData::defineNULL(int id, void *pVal)
73{
74 MemSect(17);
75 checkId(id);
76 int type = TYPE_ITEMINSTANCE;
77 shared_ptr<DataItem> dataItem = shared_ptr<DataItem>( new DataItem(type, id, shared_ptr<ItemInstance>()) );
78 itemsById[id] = dataItem;
79 MemSect(0);
80 m_isEmpty = false;
81}
82
83void SynchedEntityData::checkId(int id)
84{
85#if 0
86 if (id > MAX_ID_VALUE)
87 {
88 throw new IllegalArgumentException(L"Data value id is too big with " + _toString<int>(id) + L"! (Max is " + _toString<int>(MAX_ID_VALUE) + L")");
89 }
90 if (itemsById.find(id) != itemsById.end())
91 {
92 throw new IllegalArgumentException(L"Duplicate id value for " + _toString<int>(id) + L"!");
93 }
94#endif
95}
96
97byte SynchedEntityData::getByte(int id)
98{
99 return itemsById[id]->getValue_byte();
100}
101
102short SynchedEntityData::getShort(int id)
103{
104 return itemsById[id]->getValue_short();
105}
106
107int SynchedEntityData::getInteger(int id)
108{
109 return itemsById[id]->getValue_int();
110}
111
112float SynchedEntityData::getFloat(int id)
113{
114 return itemsById[id]->getValue_float();
115}
116
117wstring SynchedEntityData::getString(int id)
118{
119 return itemsById[id]->getValue_wstring();
120}
121
122shared_ptr<ItemInstance> SynchedEntityData::getItemInstance(int id)
123{
124 //assert(false); // 4J - not currently implemented
125 return itemsById[id]->getValue_itemInstance();
126}
127
128Pos *SynchedEntityData::getPos(int id)
129{
130 assert(false); // 4J - not currently implemented
131 return NULL;
132}
133
134void SynchedEntityData::set(int id, int value)
135{
136 shared_ptr<DataItem> dataItem = itemsById[id];
137
138 // update the value if it has changed
139 if (value != dataItem->getValue_int())
140 {
141 dataItem->setValue(value);
142 dataItem->setDirty(true);
143 m_isDirty = true;
144 }
145}
146
147void SynchedEntityData::set(int id, byte value)
148{
149 shared_ptr<DataItem> dataItem = itemsById[id];
150
151 // update the value if it has changed
152 if (value != dataItem->getValue_byte())
153 {
154 dataItem->setValue(value);
155 dataItem->setDirty(true);
156 m_isDirty = true;
157 }
158}
159
160void SynchedEntityData::set(int id, short value)
161{
162 shared_ptr<DataItem> dataItem = itemsById[id];
163
164 // update the value if it has changed
165 if (value != dataItem->getValue_short())
166 {
167 dataItem->setValue(value);
168 dataItem->setDirty(true);
169 m_isDirty = true;
170 }
171}
172
173void SynchedEntityData::set(int id, float value)
174{
175 shared_ptr<DataItem> dataItem = itemsById[id];
176
177 // update the value if it has changed
178 if (value != dataItem->getValue_float())
179 {
180 dataItem->setValue(value);
181 dataItem->setDirty(true);
182 m_isDirty = true;
183 }
184}
185
186void SynchedEntityData::set(int id, const wstring& value)
187{
188 shared_ptr<DataItem> dataItem = itemsById[id];
189
190 // update the value if it has changed
191 if (value != dataItem->getValue_wstring())
192 {
193 dataItem->setValue(value);
194 dataItem->setDirty(true);
195 m_isDirty = true;
196 }
197}
198
199void SynchedEntityData::set(int id, shared_ptr<ItemInstance> value)
200{
201 shared_ptr<DataItem> dataItem = itemsById[id];
202
203 // update the value if it has changed
204 if (value != dataItem->getValue_itemInstance())
205 {
206 dataItem->setValue(value);
207 dataItem->setDirty(true);
208 m_isDirty = true;
209 }
210}
211
212void SynchedEntityData::markDirty(int id)
213{
214 itemsById[id]->dirty = true;
215 m_isDirty = true;
216}
217
218bool SynchedEntityData::isDirty()
219{
220 return m_isDirty;
221}
222
223void SynchedEntityData::pack(vector<shared_ptr<DataItem> > *items, DataOutputStream *output) // TODO throws IOException
224{
225
226 if (items != NULL)
227 {
228 AUTO_VAR(itEnd, items->end());
229 for (AUTO_VAR(it, items->begin()); it != itEnd; it++)
230 {
231 shared_ptr<DataItem> dataItem = *it;
232 writeDataItem(output, dataItem);
233 }
234 }
235
236 // add an eof
237 output->writeByte(EOF_MARKER);
238}
239
240vector<shared_ptr<SynchedEntityData::DataItem> > *SynchedEntityData::packDirty()
241{
242
243 vector<shared_ptr<DataItem> > *result = NULL;
244
245 if (m_isDirty)
246 {
247 for( int i = 0; i <= MAX_ID_VALUE; i++ )
248 {
249 shared_ptr<DataItem> dataItem = itemsById[i];
250 if ((dataItem != NULL) && dataItem->isDirty())
251 {
252 dataItem->setDirty(false);
253
254 if (result == NULL)
255 {
256 result = new vector<shared_ptr<DataItem> >();
257 }
258 result->push_back(dataItem);
259 }
260 }
261 }
262 m_isDirty = false;
263
264 return result;
265}
266
267void SynchedEntityData::packAll(DataOutputStream *output) // throws IOException
268{
269 for( int i = 0; i <= MAX_ID_VALUE; i++ )
270 {
271 shared_ptr<DataItem> dataItem = itemsById[i];
272 if(dataItem != NULL)
273 {
274 writeDataItem(output, dataItem);
275 }
276 }
277
278 // add an eof
279 output->writeByte(EOF_MARKER);
280}
281
282vector<shared_ptr<SynchedEntityData::DataItem> > *SynchedEntityData::getAll()
283{
284 vector<shared_ptr<DataItem> > *result = NULL;
285
286 for( int i = 0; i <= MAX_ID_VALUE; i++ )
287 {
288 shared_ptr<DataItem> dataItem = itemsById[i];
289 if(dataItem != NULL)
290 {
291 if (result == NULL)
292 {
293 result = new vector<shared_ptr<DataItem> >();
294 }
295 result->push_back(dataItem);
296 }
297 }
298
299 return result;
300}
301
302
303void SynchedEntityData::writeDataItem(DataOutputStream *output, shared_ptr<DataItem> dataItem) //throws IOException
304{
305 // pack type and id
306 int header = ((dataItem->getType() << TYPE_SHIFT) | (dataItem->getId() & MAX_ID_VALUE)) & 0xff;
307 output->writeByte(header);
308
309 // write value
310 switch (dataItem->getType())
311 {
312 case TYPE_BYTE:
313 output->writeByte( dataItem->getValue_byte());
314 break;
315 case TYPE_INT:
316 output->writeInt( dataItem->getValue_int());
317 break;
318 case TYPE_SHORT:
319 output->writeShort( dataItem->getValue_short());
320 break;
321 case TYPE_FLOAT:
322 output->writeFloat( dataItem->getValue_float());
323 break;
324 case TYPE_STRING:
325 Packet::writeUtf(dataItem->getValue_wstring(), output);
326 break;
327 case TYPE_ITEMINSTANCE:
328 {
329 shared_ptr<ItemInstance> instance = (shared_ptr<ItemInstance> )dataItem->getValue_itemInstance();
330 Packet::writeItem(instance, output);
331 }
332 break;
333
334 default:
335 assert(false); // 4J - not implemented
336 break;
337 }
338}
339
340vector<shared_ptr<SynchedEntityData::DataItem> > *SynchedEntityData::unpack(DataInputStream *input) //throws IOException
341{
342
343 vector<shared_ptr<DataItem> > *result = NULL;
344
345 int currentHeader = input->readByte();
346
347 while (currentHeader != EOF_MARKER)
348 {
349
350 if (result == NULL)
351 {
352 result = new vector<shared_ptr<DataItem> >();
353 }
354
355 // split type and id
356 int itemType = (currentHeader & TYPE_MASK) >> TYPE_SHIFT;
357 int itemId = (currentHeader & MAX_ID_VALUE);
358
359 shared_ptr<DataItem> item = shared_ptr<DataItem>();
360 switch (itemType)
361 {
362 case TYPE_BYTE:
363 {
364 byte dataRead = input->readByte();
365 item = shared_ptr<DataItem>( new DataItem(itemType, itemId, dataRead) );
366 }
367 break;
368 case TYPE_SHORT:
369 {
370 short dataRead = input->readShort();
371 item = shared_ptr<DataItem>( new DataItem(itemType, itemId, dataRead) );
372 }
373 break;
374 case TYPE_INT:
375 {
376 int dataRead = input->readInt();
377 item = shared_ptr<DataItem>( new DataItem(itemType, itemId, dataRead) );
378 }
379 break;
380 case TYPE_FLOAT:
381 {
382 float dataRead = input->readFloat();
383 item = shared_ptr<DataItem>( new DataItem(itemType, itemId, dataRead) );
384
385 }
386 break;
387 case TYPE_STRING:
388 item = shared_ptr<DataItem>( new DataItem(itemType, itemId, Packet::readUtf(input, MAX_STRING_DATA_LENGTH)) );
389 break;
390 case TYPE_ITEMINSTANCE:
391 {
392 item = shared_ptr<DataItem>(new DataItem(itemType, itemId, Packet::readItem(input)));
393 }
394 break;
395 default:
396 app.DebugPrintf(" ------ garbage data, or early end of stream due to an incomplete packet\n");
397 delete result;
398 return NULL;
399 break;
400 }
401 result->push_back(item);
402
403 currentHeader = input->readByte();
404 }
405
406 return result;
407}
408
409/**
410* Assigns values from a list of data items.
411*
412* @param items
413*/
414
415void SynchedEntityData::assignValues(vector<shared_ptr<DataItem> > *items)
416{
417 AUTO_VAR(itEnd, items->end());
418 for (AUTO_VAR(it, items->begin()); it != itEnd; it++)
419 {
420 shared_ptr<DataItem> item = *it;
421
422 shared_ptr<DataItem> itemFromId = itemsById[item->getId()];
423 if( itemFromId != NULL )
424 {
425 switch(item->getType())
426 {
427 case TYPE_BYTE:
428 itemFromId->setValue(item->getValue_byte());
429 break;
430 case TYPE_SHORT:
431 itemFromId->setValue(item->getValue_short());
432 break;
433 case TYPE_INT:
434 itemFromId->setValue(item->getValue_int());
435 break;
436 case TYPE_FLOAT:
437 itemFromId->setValue(item->getValue_float());
438 break;
439 case TYPE_STRING:
440 itemFromId->setValue(item->getValue_wstring());
441 break;
442 case TYPE_ITEMINSTANCE:
443 itemFromId->setValue(item->getValue_itemInstance());
444 break;
445 default:
446 assert(false); // 4J - not implemented
447 break;
448 }
449 }
450 }
451
452 // client-side dirty
453 m_isDirty = true;
454}
455
456bool SynchedEntityData::isEmpty()
457{
458 return m_isEmpty;
459}
460
461void SynchedEntityData::clearDirty()
462{
463 m_isDirty = false;
464}
465
466int SynchedEntityData::getSizeInBytes()
467{
468 int size = 1;
469
470 for( int i = 0; i <= MAX_ID_VALUE; i++ )
471 {
472 shared_ptr<DataItem> dataItem = itemsById[i];
473 if(dataItem != NULL)
474 {
475 size += 1;
476
477 // write value
478 switch (dataItem->getType())
479 {
480 case TYPE_BYTE:
481 size += 1;
482 break;
483 case TYPE_SHORT:
484 size += 2;
485 break;
486 case TYPE_INT:
487 size += 4;
488 break;
489 case TYPE_FLOAT:
490 size += 4;
491 break;
492 case TYPE_STRING:
493 size += (int)dataItem->getValue_wstring().length() + 2; // Estimate, assuming all ascii chars
494 break;
495 case TYPE_ITEMINSTANCE:
496 // short + byte + short
497 size += 2 + 1 + 2; // Estimate, assuming all ascii chars
498 break;
499 default:
500 break;
501 }
502 }
503 }
504 return size;
505}
506
507
508//////////////////
509// DataItem class
510/////////////////
511
512SynchedEntityData::DataItem::DataItem(int type, int id, int value) : type( type ), id( id )
513{
514 this->value_int = value;
515 this->dirty = true;
516}
517
518SynchedEntityData::DataItem::DataItem(int type, int id, byte value) : type( type ), id( id )
519{
520 this->value_byte = value;
521 this->dirty = true;
522}
523
524SynchedEntityData::DataItem::DataItem(int type, int id, short value) : type( type ), id( id )
525{
526 this->value_short = value;
527 this->dirty = true;
528}
529
530SynchedEntityData::DataItem::DataItem(int type, int id, float value) : type( type ), id( id )
531{
532 this->value_float = value;
533 this->dirty = true;
534}
535
536SynchedEntityData::DataItem::DataItem(int type, int id, const wstring& value) : type( type ), id( id )
537{
538 this->value_wstring = value;
539 this->dirty = true;
540}
541
542SynchedEntityData::DataItem::DataItem(int type, int id, shared_ptr<ItemInstance> itemInstance) : type( type ), id( id )
543{
544 this->value_itemInstance = itemInstance;
545 this->dirty = true;
546}
547
548int SynchedEntityData::DataItem::getId()
549{
550 return id;
551}
552
553void SynchedEntityData::DataItem::setValue(int value)
554{
555 this->value_int = value;
556}
557
558void SynchedEntityData::DataItem::setValue(byte value)
559{
560 this->value_byte = value;
561}
562
563void SynchedEntityData::DataItem::setValue(short value)
564{
565 this->value_short = value;
566}
567
568void SynchedEntityData::DataItem::setValue(float value)
569{
570 this->value_float = value;
571}
572
573void SynchedEntityData::DataItem::setValue(const wstring& value)
574{
575 this->value_wstring = value;
576}
577
578void SynchedEntityData::DataItem::setValue(shared_ptr<ItemInstance> itemInstance)
579{
580 this->value_itemInstance = itemInstance;
581}
582
583int SynchedEntityData::DataItem::getValue_int()
584{
585 return value_int;
586}
587
588short SynchedEntityData::DataItem::getValue_short()
589{
590 return value_short;
591}
592
593float SynchedEntityData::DataItem::getValue_float()
594{
595 return value_float;
596}
597
598byte SynchedEntityData::DataItem::getValue_byte()
599{
600 return value_byte;
601}
602
603wstring SynchedEntityData::DataItem::getValue_wstring()
604{
605 return value_wstring;
606}
607
608shared_ptr<ItemInstance> SynchedEntityData::DataItem::getValue_itemInstance()
609{
610 return value_itemInstance;
611}
612
613int SynchedEntityData::DataItem::getType()
614{
615 return type;
616}
617
618bool SynchedEntityData::DataItem::isDirty()
619{
620 return dirty;
621}
622
623void SynchedEntityData::DataItem::setDirty(bool dirty)
624{
625 this->dirty = dirty;
626}