354d022967
commit f44d146e4ac906ff898e8968c6857fd2280f6d20 Author: project-bo4 <127137346+project-bo4@users.noreply.github.com> Date: Thu May 11 13:39:29 2023 -0700 remove lpc package from repository commit 29fb0f63e50de468ab0b9db35f7e8fdadf58afc3 Author: project-bo4 <themanwithantidote@gmail.com> Date: Thu May 11 13:06:13 2023 -0700 generic improvements + added identity configuration + objectstore improvements + added battlenet 'US' servers to blocklist + some other minor improvements commit 5d5e31099ebcce5a637b9a02d4936a97fb0802a7 Author: project-bo4 <themanwithantidote@gmail.com> Date: Sat Mar 25 16:32:52 2023 -0700 lpc improvements + fix lpc issue with foreign languages(non-english) not being considered in listing + check lpc files pre-start and warn user if missing any of core items commit 2de1a54b6f4cc5c44dc906871021cfbc85057ca9 Author: project-bo4 <themanwithantidote@gmail.com> Date: Thu Mar 23 12:45:56 2023 -0700 demonware improvements + handle object store uploadUserObject + silence bdUNK125 commit 710dcc3ec6178071d67c27e5bf6705f08cabe7e2 Author: project-bo4 <themanwithantidote@gmail.com> Date: Mon Mar 20 13:43:56 2023 -0700 forgot to update names commit 217682dfb07b35f7a09399fb2698924bb7fe8b77 Author: project-bo4 <themanwithantidote@gmail.com> Date: Mon Mar 20 11:09:18 2023 -0700 upload lpc and update readme commit 83f812b33b90791a8d13b9468f27da51e0a4f2b9 Author: project-bo4 <themanwithantidote@gmail.com> Date: Mon Mar 20 10:53:43 2023 -0700 demonware emulator + demonware emulator + platform name and id + xxhash and picoproto - remove g_runframe hook -disable discovery(save time) + improvements to utils + add new resources
183 lines
3.8 KiB
C++
183 lines
3.8 KiB
C++
#include <std_include.hpp>
|
|
#include "bit_buffer.hpp"
|
|
|
|
namespace demonware
|
|
{
|
|
bool bit_buffer::read_bytes(const unsigned int bytes, unsigned char* output)
|
|
{
|
|
return this->read(bytes * 8, output);
|
|
}
|
|
|
|
bool bit_buffer::read_bool(bool* output)
|
|
{
|
|
if (!this->read_data_type(1))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return this->read(1, output);
|
|
}
|
|
|
|
bool bit_buffer::read_uint32(unsigned int* output)
|
|
{
|
|
if (!this->read_data_type(8))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return this->read(32, output);
|
|
}
|
|
|
|
bool bit_buffer::read_data_type(const char expected)
|
|
{
|
|
char data_type = 0;
|
|
|
|
if (!this->use_data_types_) return true;
|
|
if (this->read(5, &data_type))
|
|
{
|
|
return (data_type == expected);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool bit_buffer::write_bytes(const unsigned int bytes, const char* data)
|
|
{
|
|
return this->write_bytes(bytes, reinterpret_cast<const unsigned char*>(data));
|
|
}
|
|
|
|
bool bit_buffer::write_bytes(const unsigned int bytes, const unsigned char* data)
|
|
{
|
|
return this->write(bytes * 8, data);
|
|
}
|
|
|
|
bool bit_buffer::write_bool(bool data)
|
|
{
|
|
if (this->write_data_type(1))
|
|
{
|
|
return this->write(1, &data);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool bit_buffer::write_int32(int data)
|
|
{
|
|
if (this->write_data_type(7))
|
|
{
|
|
return this->write(32, &data);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool bit_buffer::write_uint32(unsigned int data)
|
|
{
|
|
if (this->write_data_type(8))
|
|
{
|
|
return this->write(32, &data);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool bit_buffer::write_data_type(char data)
|
|
{
|
|
if (!this->use_data_types_)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return this->write(5, &data);
|
|
}
|
|
|
|
bool bit_buffer::read(unsigned int bits, void* output)
|
|
{
|
|
if (bits == 0) return false;
|
|
if ((this->current_bit_ + bits) > (this->buffer_.size() * 8)) return false;
|
|
|
|
int cur_byte = this->current_bit_ >> 3;
|
|
auto cur_out = 0;
|
|
|
|
const char* bytes = this->buffer_.data();
|
|
const auto output_bytes = static_cast<unsigned char*>(output);
|
|
|
|
while (bits > 0)
|
|
{
|
|
const int min_bit = (bits < 8) ? bits : 8;
|
|
const auto this_byte = bytes[cur_byte++] & 0xFF;
|
|
const int remain = this->current_bit_ & 7;
|
|
|
|
if ((min_bit + remain) <= 8)
|
|
{
|
|
output_bytes[cur_out] = BYTE((0xFF >> (8 - min_bit)) & (this_byte >> remain));
|
|
}
|
|
else
|
|
{
|
|
output_bytes[cur_out] = BYTE(
|
|
(0xFF >> (8 - min_bit)) & (bytes[cur_byte] << (8 - remain)) | (this_byte >> remain));
|
|
}
|
|
|
|
cur_out++;
|
|
this->current_bit_ += min_bit;
|
|
bits -= min_bit;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool bit_buffer::write(const unsigned int bits, const void* data)
|
|
{
|
|
if (bits == 0) return false;
|
|
this->buffer_.resize(this->buffer_.size() + (bits >> 3) + 1);
|
|
|
|
int bit = bits;
|
|
const auto bytes = const_cast<char*>(this->buffer_.data());
|
|
const auto* input_bytes = static_cast<const unsigned char*>(data);
|
|
|
|
while (bit > 0)
|
|
{
|
|
const int bit_pos = this->current_bit_ & 7;
|
|
auto rem_bit = 8 - bit_pos;
|
|
const auto this_write = (bit < rem_bit) ? bit : rem_bit;
|
|
|
|
const BYTE mask = ((0xFF >> rem_bit) | (0xFF << (bit_pos + this_write)));
|
|
const int byte_pos = this->current_bit_ >> 3;
|
|
|
|
const BYTE temp_byte = (mask & bytes[byte_pos]);
|
|
const BYTE this_bit = ((bits - bit) & 7);
|
|
const auto this_byte = (bits - bit) >> 3;
|
|
|
|
auto this_data = input_bytes[this_byte];
|
|
|
|
const auto next_byte = (((bits - 1) >> 3) > this_byte) ? input_bytes[this_byte + 1] : 0;
|
|
|
|
this_data = BYTE((next_byte << (8 - this_bit)) | (this_data >> this_bit));
|
|
|
|
const BYTE out_byte = (~mask & (this_data << bit_pos) | temp_byte);
|
|
bytes[byte_pos] = out_byte;
|
|
|
|
this->current_bit_ += this_write;
|
|
bit -= this_write;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void bit_buffer::set_use_data_types(const bool use_data_types)
|
|
{
|
|
this->use_data_types_ = use_data_types;
|
|
}
|
|
|
|
unsigned int bit_buffer::size() const
|
|
{
|
|
return this->current_bit_ / 8 + (this->current_bit_ % 8 ? 1 : 0);
|
|
}
|
|
|
|
std::string& bit_buffer::get_buffer()
|
|
{
|
|
this->buffer_.resize(this->size());
|
|
return this->buffer_;
|
|
}
|
|
}
|