|
|
@@ -32,31 +32,56 @@ constexpr std::uint32_t kModifierClass = 0x80807490U;
|
|
|
constexpr std::uint32_t kSocketClass = 0x80803062U;
|
|
|
constexpr std::uint32_t kWrapperClass = 0x808077CCU;
|
|
|
constexpr std::uint32_t kSelectionClass = 0x808077CFU;
|
|
|
-constexpr std::uint32_t kFlagTableClass = 0x80807D49U, kFlagRowClass = 0x80807D4FU;
|
|
|
-constexpr std::uint32_t kValueTableClass = 0x80807C92U, kValueRowClass = 0x80807C96U;
|
|
|
-constexpr std::uint32_t kExpressionTableClass = 0x80807C49U, kExpressionRowClass = 0x80807C4FU;
|
|
|
+constexpr std::uint32_t kFlagTableClass = 0x80807D49U;
|
|
|
+constexpr std::uint32_t kFlagRowClass = 0x80807D4FU;
|
|
|
+constexpr std::uint32_t kValueTableClass = 0x80807C92U;
|
|
|
+constexpr std::uint32_t kValueRowClass = 0x80807C96U;
|
|
|
+constexpr std::uint32_t kExpressionTableClass = 0x80807C49U;
|
|
|
+constexpr std::uint32_t kExpressionRowClass = 0x80807C4FU;
|
|
|
constexpr std::uint32_t kConditionClass = 0x80807D2FU;
|
|
|
-constexpr std::size_t kPoolStride = 24, kEntryStride = 80, kModifierStride = 24;
|
|
|
-constexpr std::size_t kBindingStride = 8, kExpressionRowStride = 24;
|
|
|
-constexpr std::size_t kSocketStride = 12, kSelectionStride = 12;
|
|
|
+constexpr std::size_t kPoolStride = 24;
|
|
|
+constexpr std::size_t kEntryStride = 80;
|
|
|
+constexpr std::size_t kModifierStride = 24;
|
|
|
+constexpr std::size_t kBindingStride = 8;
|
|
|
+constexpr std::size_t kExpressionRowStride = 24;
|
|
|
+constexpr std::size_t kSocketStride = 12;
|
|
|
+constexpr std::size_t kSelectionStride = 12;
|
|
|
/** Item headers hold a relative wrapper pointer and an acquired-unlock slot. */
|
|
|
constexpr std::size_t kWrapperField = 0x58;
|
|
|
constexpr std::size_t kAcquiredFlagField = 0xDA;
|
|
|
|
|
|
/** Byte offsets inside the serialized reward rows. */
|
|
|
-constexpr std::size_t kEntryQuantityOffset = 4, kEntryPoolOffset = 8;
|
|
|
-constexpr std::size_t kEntryCategoryOffset = 20, kEntryWeightOffset = 24;
|
|
|
-constexpr std::size_t kEntryBucketOffset = 28, kEntryConditionOffset = 32;
|
|
|
-constexpr std::size_t kEntryModifiersOffset = 48, kEntrySocketsOffset = 64;
|
|
|
-constexpr std::size_t kModifierValueIndexOffset = 16, kModifierValueOffset = 20;
|
|
|
-constexpr std::size_t kPoolEntriesOffset = 8, kExpressionBodyOffset = 8;
|
|
|
-constexpr std::size_t kWrapperSelectionsOffset = 8, kWrapperFlagsOffset = 24;
|
|
|
+constexpr std::size_t kEntryQuantityOffset = 4;
|
|
|
+constexpr std::size_t kEntryPoolOffset = 8;
|
|
|
+constexpr std::size_t kEntryCategoryOffset = 20;
|
|
|
+constexpr std::size_t kEntryWeightOffset = 24;
|
|
|
+constexpr std::size_t kEntryBucketOffset = 28;
|
|
|
+constexpr std::size_t kEntryConditionOffset = 32;
|
|
|
+constexpr std::size_t kEntryModifiersOffset = 48;
|
|
|
+constexpr std::size_t kEntrySocketsOffset = 64;
|
|
|
+constexpr std::size_t kModifierValueIndexOffset = 16;
|
|
|
+constexpr std::size_t kModifierValueOffset = 20;
|
|
|
+constexpr std::size_t kPoolEntriesOffset = 8;
|
|
|
+constexpr std::size_t kExpressionBodyOffset = 8;
|
|
|
+constexpr std::size_t kWrapperSelectionsOffset = 8;
|
|
|
+constexpr std::size_t kWrapperFlagsOffset = 24;
|
|
|
constexpr std::size_t kSelectionCountOffset = 4;
|
|
|
-constexpr std::size_t kSocketPlugOffset = 2, kSocketPlugSetOffset = 4;
|
|
|
-constexpr std::size_t kSocketRollSetOffset = 6, kSocketSelectionOffset = 8;
|
|
|
+constexpr std::size_t kSocketPlugOffset = 2;
|
|
|
+constexpr std::size_t kSocketPlugSetOffset = 4;
|
|
|
+constexpr std::size_t kSocketRollSetOffset = 6;
|
|
|
+constexpr std::size_t kSocketSelectionOffset = 8;
|
|
|
/** Relative definition bodies are preceded by their four-byte schema class. */
|
|
|
constexpr std::size_t kDefinitionClassPrefixSize = sizeof(std::uint32_t);
|
|
|
|
|
|
+// Class rows name a default finisher whose use gate supplies the computed class flag.
|
|
|
+constexpr std::size_t kClassSlot = 12;
|
|
|
+constexpr std::size_t kClassStride = 32;
|
|
|
+constexpr std::size_t kDefaultFinisherOffset = 24;
|
|
|
+constexpr std::uint32_t kClassTable = 0x808075BEU;
|
|
|
+constexpr std::uint32_t kClassRow = 0x808074FAU;
|
|
|
+constexpr std::size_t kUseConditionPointer = 24;
|
|
|
+constexpr std::uint32_t kUseConditionClass = 0x80802980U;
|
|
|
+
|
|
|
template <typename T> bool append(std::vector<T>& bank, T value, std::size_t capacity) noexcept {
|
|
|
if (bank.size() >= capacity) {
|
|
|
return false;
|
|
|
@@ -94,12 +119,42 @@ bool read_reward_entry(std::span<const std::byte> blob,
|
|
|
&& std::isfinite(entry.weight) && entry.weight >= 0;
|
|
|
}
|
|
|
|
|
|
+/** Reads the single flag that gates use of the class's default finisher. */
|
|
|
+bool read_class_flag(std::span<const std::byte> blob, std::uint16_t& output) noexcept {
|
|
|
+ std::int64_t relative = 0;
|
|
|
+ if (!tables::read(blob, kUseConditionPointer, relative) || relative <= 0
|
|
|
+ || static_cast<std::uint64_t>(relative) > blob.size()
|
|
|
+ || kUseConditionPointer > blob.size() - static_cast<std::size_t>(relative)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ const auto at = kUseConditionPointer + static_cast<std::size_t>(relative);
|
|
|
+ std::uint32_t cls = 0;
|
|
|
+ tables::Array expression{};
|
|
|
+ if (!tables::read(blob, at - kDefinitionClassPrefixSize, cls) || cls != kUseConditionClass
|
|
|
+ || !tables::read_array(
|
|
|
+ blob, at, kExpressionClass, tables::kUnlockInstructionStride, expression)
|
|
|
+ || expression.count != 1) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ std::uint32_t opcode = 0;
|
|
|
+ std::uint32_t flag = domain::kAbsent;
|
|
|
+ if (!tables::read(blob, expression.dataOffset, opcode)
|
|
|
+ || opcode != static_cast<std::uint32_t>(tables::UnlockOpcode::flag)
|
|
|
+ || !tables::read(
|
|
|
+ blob, expression.dataOffset + tables::kUnlockInstructionOperandOffset, flag)
|
|
|
+ || flag >= domain::kAbsent) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ output = static_cast<std::uint16_t>(flag);
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
} // namespace
|
|
|
|
|
|
bool RewardBuild::entry(std::span<const std::byte> blob, std::size_t at) noexcept {
|
|
|
domain::Entry out{};
|
|
|
if (!read_reward_entry(blob, at, out)
|
|
|
- || !conditions.read(blob, at + kEntryConditionOffset, instructions, out.condition)) {
|
|
|
+ || !conditions.read(blob, at + kEntryConditionOffset, instructions_, out.condition)) {
|
|
|
return false;
|
|
|
}
|
|
|
tables::Array rows{};
|
|
|
@@ -107,46 +162,44 @@ bool RewardBuild::entry(std::span<const std::byte> blob, std::size_t at) noexcep
|
|
|
blob, at + kEntryModifiersOffset, kModifierClass, kModifierStride, rows)) {
|
|
|
return false;
|
|
|
}
|
|
|
- out.modifiers = {static_cast<std::uint32_t>(modifiers.size()),
|
|
|
+ out.modifiers = {static_cast<std::uint32_t>(modifiers_.size()),
|
|
|
static_cast<std::uint32_t>(rows.count)};
|
|
|
for (std::size_t i = 0; i < rows.count; ++i) {
|
|
|
const auto offset = rows.dataOffset + i * kModifierStride;
|
|
|
domain::Modifier modifier{};
|
|
|
- if (!conditions.read(blob, offset, instructions, modifier.condition)
|
|
|
+ if (!conditions.read(blob, offset, instructions_, modifier.condition)
|
|
|
|| !tables::read(blob, offset + kModifierValueIndexOffset, modifier.valueIndex)
|
|
|
|| !tables::read(blob, offset + kModifierValueOffset, modifier.value)
|
|
|
|| !std::isfinite(modifier.value)
|
|
|
- || !append(modifiers, modifier, domain::kModifierCapacity)) {
|
|
|
+ || !append(modifiers_, modifier, domain::kModifierCapacity)) {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
std::array<domain::SocketOverride, domain::kSocketsPerItem> overrides{};
|
|
|
std::size_t count = 0;
|
|
|
if (!read_reward_sockets(blob, at + kEntrySocketsOffset, overrides, count)
|
|
|
- || count > domain::kSocketOverrideCapacity - sockets.size()) {
|
|
|
+ || count > domain::kSocketOverrideCapacity - sockets_.size()) {
|
|
|
return false;
|
|
|
}
|
|
|
- out.sockets = {static_cast<std::uint32_t>(sockets.size()), static_cast<std::uint32_t>(count)};
|
|
|
+ out.sockets = {static_cast<std::uint32_t>(sockets_.size()), static_cast<std::uint32_t>(count)};
|
|
|
for (std::size_t i = 0; i < count; ++i) {
|
|
|
if (overrides[i].socketType == domain::kAbsent
|
|
|
- || !append(sockets, overrides[i], domain::kSocketOverrideCapacity)) {
|
|
|
+ || !append(sockets_, overrides[i], domain::kSocketOverrideCapacity)) {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
- return append(entries, out, domain::kEntryCapacity);
|
|
|
+ return append(entries_, out, domain::kEntryCapacity);
|
|
|
}
|
|
|
|
|
|
void RewardConditions::load_class_flags(const reader::Source& source,
|
|
|
reader::Scratch& scratch,
|
|
|
std::span<const std::byte> root) noexcept {
|
|
|
classFlags_.fill(domain::kAbsent);
|
|
|
- // Class rows name a default finisher whose use gate supplies the computed class flag.
|
|
|
- constexpr std::size_t kClassSlot = 12, kClassStride = 32, kDefaultFinisherOffset = 24;
|
|
|
- constexpr std::uint32_t kClassTable = 0x808075BEU, kClassRow = 0x808074FAU;
|
|
|
- constexpr std::size_t kUseConditionPointer = 24;
|
|
|
- constexpr std::uint32_t kUseConditionClass = 0x80802980U;
|
|
|
- std::vector<std::byte> classes, index, blob;
|
|
|
- tables::Array classRows{}, itemRows{};
|
|
|
+ std::vector<std::byte> classes;
|
|
|
+ std::vector<std::byte> index;
|
|
|
+ std::vector<std::byte> blob;
|
|
|
+ tables::Array classRows{};
|
|
|
+ tables::Array itemRows{};
|
|
|
if (!root_table(source, scratch, root, kClassSlot, classes, kClassTable)
|
|
|
|| !tables::read_array(
|
|
|
classes, tables::kTableArrayDescriptor, kClassRow, kClassStride, classRows)
|
|
|
@@ -165,18 +218,13 @@ void RewardConditions::load_class_flags(const reader::Source& source,
|
|
|
for (std::size_t i = 0; i < classFlags_.size(); ++i) {
|
|
|
std::uint16_t itemIndex = domain::kAbsent;
|
|
|
tables::IndexRow item{};
|
|
|
- tables::Array condition{};
|
|
|
- std::uint32_t cls = 0, opcode = 0, flag = domain::kAbsent;
|
|
|
- std::int64_t relative = 0;
|
|
|
+ std::uint32_t cls = 0;
|
|
|
if (!tables::read(std::span<const std::byte>{classes},
|
|
|
classRows.dataOffset + i * kClassStride + kDefaultFinisherOffset,
|
|
|
itemIndex)
|
|
|
|| !tables::index_row(index, itemRows, itemIndex, item)
|
|
|
|| !reader::read_tag(source, scratch, item.targetTag, blob, cls)
|
|
|
- || cls != tables::kItemDefinitionClass
|
|
|
- || !tables::read(std::span<const std::byte>{blob}, kUseConditionPointer, relative)
|
|
|
- || relative <= 0 || static_cast<std::uint64_t>(relative) > blob.size()
|
|
|
- || kUseConditionPointer > blob.size() - static_cast<std::size_t>(relative)) {
|
|
|
+ || cls != tables::kItemDefinitionClass) {
|
|
|
core::log::writef(
|
|
|
core::log::Channel::client,
|
|
|
core::log::Level::warn,
|
|
|
@@ -184,20 +232,7 @@ void RewardConditions::load_class_flags(const reader::Source& source,
|
|
|
i);
|
|
|
continue;
|
|
|
}
|
|
|
- const auto at = kUseConditionPointer + static_cast<std::size_t>(relative);
|
|
|
- if (tables::read(std::span<const std::byte>{blob}, at - kDefinitionClassPrefixSize, cls)
|
|
|
- && cls == kUseConditionClass
|
|
|
- && tables::read_array(
|
|
|
- blob, at, kExpressionClass, tables::kUnlockInstructionStride, condition)
|
|
|
- && condition.count == 1
|
|
|
- && tables::read(std::span<const std::byte>{blob}, condition.dataOffset, opcode)
|
|
|
- && opcode == static_cast<std::uint32_t>(tables::UnlockOpcode::flag)
|
|
|
- && tables::read(std::span<const std::byte>{blob},
|
|
|
- condition.dataOffset + tables::kUnlockInstructionOperandOffset,
|
|
|
- flag)
|
|
|
- && flag < domain::kAbsent) {
|
|
|
- classFlags_[i] = static_cast<std::uint16_t>(flag);
|
|
|
- } else {
|
|
|
+ if (!read_class_flag(blob, classFlags_[i])) {
|
|
|
core::log::writef(core::log::Channel::client,
|
|
|
core::log::Level::warn,
|
|
|
"ev=pkg stage=class_flags class=%zu result=skip reason=use_condition",
|
|
|
@@ -229,10 +264,9 @@ bool RewardConditions::load(const reader::Source& source,
|
|
|
}
|
|
|
|
|
|
bool RewardConditions::bind(domain::Instruction& instruction) const noexcept {
|
|
|
- const auto opcode =
|
|
|
- static_cast<middleware::content::packages::tables::UnlockOpcode>(instruction.opcode);
|
|
|
- const bool flag = opcode == middleware::content::packages::tables::UnlockOpcode::flag;
|
|
|
- if (!flag && opcode != middleware::content::packages::tables::UnlockOpcode::loadValue) {
|
|
|
+ const auto opcode = static_cast<tables::UnlockOpcode>(instruction.opcode);
|
|
|
+ const bool flag = opcode == tables::UnlockOpcode::flag;
|
|
|
+ if (!flag && opcode != tables::UnlockOpcode::loadValue) {
|
|
|
return true;
|
|
|
}
|
|
|
const auto& rows = flag ? flagRows_ : valueRows_;
|
|
|
@@ -245,13 +279,13 @@ bool RewardConditions::bind(domain::Instruction& instruction) const noexcept {
|
|
|
if (!tables::read(blob, at, hash)) {
|
|
|
return false;
|
|
|
}
|
|
|
- using B = domain::BankRead;
|
|
|
+ using Read = domain::BankRead;
|
|
|
if (flag) {
|
|
|
for (std::size_t characterClass = 0; characterClass < classFlags_.size();
|
|
|
++characterClass) {
|
|
|
if (classFlags_[characterClass] != domain::kAbsent
|
|
|
&& instruction.operand == classFlags_[characterClass]) {
|
|
|
- instruction = {static_cast<std::uint32_t>(B::characterClass),
|
|
|
+ instruction = {static_cast<std::uint32_t>(Read::characterClass),
|
|
|
static_cast<std::uint32_t>(characterClass)};
|
|
|
return true;
|
|
|
}
|
|
|
@@ -263,19 +297,21 @@ bool RewardConditions::bind(domain::Instruction& instruction) const noexcept {
|
|
|
const auto characterIndex =
|
|
|
bank_index(character, static_cast<std::int32_t>(instruction.operand));
|
|
|
if (accountIndex != kUnmappedSlot) {
|
|
|
- instruction = {static_cast<std::uint32_t>(flag ? B::accountFlag : B::accountValue),
|
|
|
+ instruction = {static_cast<std::uint32_t>(flag ? Read::accountFlag : Read::accountValue),
|
|
|
accountIndex};
|
|
|
} else if (flag
|
|
|
&& bank_index(maps_->profileFlag, static_cast<std::int32_t>(instruction.operand))
|
|
|
!= kUnmappedSlot) {
|
|
|
instruction = {
|
|
|
- static_cast<std::uint32_t>(B::profileFlag),
|
|
|
+ static_cast<std::uint32_t>(Read::profileFlag),
|
|
|
bank_index(maps_->profileFlag, static_cast<std::int32_t>(instruction.operand))};
|
|
|
} else if (characterIndex != kUnmappedSlot) {
|
|
|
- instruction = {static_cast<std::uint32_t>(flag ? B::characterFlag : B::characterValue),
|
|
|
- characterIndex};
|
|
|
+ instruction = {
|
|
|
+ static_cast<std::uint32_t>(flag ? Read::characterFlag : Read::characterValue),
|
|
|
+ characterIndex};
|
|
|
} else {
|
|
|
- instruction = {static_cast<std::uint32_t>(flag ? B::externalFlag : B::externalValue), hash};
|
|
|
+ instruction = {static_cast<std::uint32_t>(flag ? Read::externalFlag : Read::externalValue),
|
|
|
+ hash};
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
@@ -300,8 +336,8 @@ bool RewardConditions::append_expression(std::span<const std::byte> blob,
|
|
|
instruction.operand)) {
|
|
|
return false;
|
|
|
}
|
|
|
- if (static_cast<middleware::content::packages::tables::UnlockOpcode>(instruction.opcode)
|
|
|
- == middleware::content::packages::tables::UnlockOpcode::expression) {
|
|
|
+ if (static_cast<tables::UnlockOpcode>(instruction.opcode)
|
|
|
+ == tables::UnlockOpcode::expression) {
|
|
|
const auto before = bank.size();
|
|
|
if (instruction.operand >= expressionRows_.count
|
|
|
|| !append_expression(expressions_,
|
|
|
@@ -357,9 +393,7 @@ bool RewardConditions::read_list(std::span<const std::byte> blob,
|
|
|
if (i != 0
|
|
|
&& !append(instructions,
|
|
|
domain::Instruction{
|
|
|
- static_cast<std::uint32_t>(
|
|
|
- middleware::content::packages::tables::UnlockOpcode::logicalAnd),
|
|
|
- 0},
|
|
|
+ static_cast<std::uint32_t>(tables::UnlockOpcode::logicalAnd), 0},
|
|
|
output.size())) {
|
|
|
return false;
|
|
|
}
|
|
|
@@ -402,11 +436,11 @@ bool RewardBuild::load(const reader::Source& source,
|
|
|
std::span<const std::byte> root,
|
|
|
const SlotMaps& maps) noexcept {
|
|
|
loaded_ = false;
|
|
|
- pools.clear();
|
|
|
- entries.clear();
|
|
|
- instructions.clear();
|
|
|
- modifiers.clear();
|
|
|
- sockets.clear();
|
|
|
+ pools_.clear();
|
|
|
+ entries_.clear();
|
|
|
+ instructions_.clear();
|
|
|
+ modifiers_.clear();
|
|
|
+ sockets_.clear();
|
|
|
std::vector<std::byte> blob;
|
|
|
tables::Array rows{};
|
|
|
if (!conditions.load(source, scratch, root, maps)
|
|
|
@@ -424,32 +458,33 @@ bool RewardBuild::load(const reader::Source& source,
|
|
|
if (tables::read(blob, at, pool.definitionHash) && pool.definitionHash != 0
|
|
|
&& tables::read_array(
|
|
|
blob, at + kPoolEntriesOffset, kEntryClass, kEntryStride, members)) {
|
|
|
- pool.entries.first = static_cast<std::uint32_t>(entries.size());
|
|
|
+ pool.entries.first = static_cast<std::uint32_t>(entries_.size());
|
|
|
for (std::size_t j = 0; j < members.count; ++j) {
|
|
|
- const auto beforeInstructions = instructions.size(),
|
|
|
- beforeModifiers = modifiers.size(), beforeSockets = sockets.size();
|
|
|
+ const auto beforeInstructions = instructions_.size();
|
|
|
+ const auto beforeModifiers = modifiers_.size();
|
|
|
+ const auto beforeSockets = sockets_.size();
|
|
|
if (!entry(blob, members.dataOffset + j * kEntryStride)) {
|
|
|
- instructions.resize(beforeInstructions);
|
|
|
- modifiers.resize(beforeModifiers);
|
|
|
- sockets.resize(beforeSockets);
|
|
|
+ instructions_.resize(beforeInstructions);
|
|
|
+ modifiers_.resize(beforeModifiers);
|
|
|
+ sockets_.resize(beforeSockets);
|
|
|
++skipped;
|
|
|
}
|
|
|
}
|
|
|
- pool.entries.count = static_cast<std::uint32_t>(entries.size()) - pool.entries.first;
|
|
|
+ pool.entries.count = static_cast<std::uint32_t>(entries_.size()) - pool.entries.first;
|
|
|
} else {
|
|
|
pool = {};
|
|
|
++skipped;
|
|
|
}
|
|
|
- if (!append(pools, pool, domain::kPoolCapacity)) {
|
|
|
+ if (!append(pools_, pool, domain::kPoolCapacity)) {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
- if (skipped != 0) {
|
|
|
- core::log::writef(core::log::Channel::client,
|
|
|
- core::log::Level::warn,
|
|
|
- "ev=pkg stage=rewards skipped=%zu",
|
|
|
- skipped);
|
|
|
- }
|
|
|
+ core::log::writef(core::log::Channel::client,
|
|
|
+ skipped == 0 ? core::log::Level::info : core::log::Level::warn,
|
|
|
+ "ev=pkg stage=rewards pools=%zu entries=%zu skipped=%zu",
|
|
|
+ pools_.size(),
|
|
|
+ entries_.size(),
|
|
|
+ skipped);
|
|
|
loaded_ = true;
|
|
|
return true;
|
|
|
}
|
|
|
@@ -466,9 +501,7 @@ bool RewardBuild::read_item(std::uint32_t hash,
|
|
|
}
|
|
|
item.definitionHash = hash;
|
|
|
if (acquired != domain::kAbsent) {
|
|
|
- domain::Instruction flag{
|
|
|
- static_cast<std::uint32_t>(middleware::content::packages::tables::UnlockOpcode::flag),
|
|
|
- acquired};
|
|
|
+ domain::Instruction flag{static_cast<std::uint32_t>(tables::UnlockOpcode::flag), acquired};
|
|
|
if (!conditions.bind(flag) || !domain::valid_instruction(flag)) {
|
|
|
return false;
|
|
|
}
|
|
|
@@ -509,7 +542,7 @@ bool RewardBuild::begin_items(std::size_t count) noexcept {
|
|
|
if (!loaded_ || count == 0 || count > domain::kItemCapacity) {
|
|
|
return false;
|
|
|
}
|
|
|
- items.assign(count, {});
|
|
|
+ items_.assign(count, {});
|
|
|
return true;
|
|
|
} catch (...) {
|
|
|
return false;
|
|
|
@@ -520,8 +553,8 @@ void RewardBuild::item(std::uint16_t index,
|
|
|
std::uint32_t hash,
|
|
|
std::span<const std::byte> blob) noexcept {
|
|
|
domain::Item parsed{};
|
|
|
- if (index < items.size() && read_item(hash, blob, parsed)) {
|
|
|
- items[index] = parsed;
|
|
|
+ if (index < items_.size() && read_item(hash, blob, parsed)) {
|
|
|
+ items_[index] = parsed;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -529,39 +562,40 @@ bool RewardBuild::publish() noexcept {
|
|
|
if (!loaded_) {
|
|
|
return false;
|
|
|
}
|
|
|
- std::size_t write = 0, socketWrite = 0;
|
|
|
- for (auto& pool : pools) {
|
|
|
+ std::size_t write = 0;
|
|
|
+ std::size_t socketWrite = 0;
|
|
|
+ for (auto& pool : pools_) {
|
|
|
const auto range = pool.entries;
|
|
|
pool.entries.first = static_cast<std::uint32_t>(write);
|
|
|
for (std::size_t i = range.first; i < range.first + range.count; ++i) {
|
|
|
- const auto& row = entries[i];
|
|
|
- bool valid = (row.itemIndex == domain::kAbsent || row.itemIndex < items.size())
|
|
|
- && (row.poolIndex == domain::kAbsent || row.poolIndex < pools.size());
|
|
|
+ const auto& row = entries_[i];
|
|
|
+ bool valid = (row.itemIndex == domain::kAbsent || row.itemIndex < items_.size())
|
|
|
+ && (row.poolIndex == domain::kAbsent || row.poolIndex < pools_.size());
|
|
|
for (const auto& socket :
|
|
|
- std::span(sockets).subspan(row.sockets.first, row.sockets.count)) {
|
|
|
- valid &= socket.plugItem == domain::kAbsent || socket.plugItem < items.size();
|
|
|
+ std::span(sockets_).subspan(row.sockets.first, row.sockets.count)) {
|
|
|
+ valid &= socket.plugItem == domain::kAbsent || socket.plugItem < items_.size();
|
|
|
}
|
|
|
if (valid) {
|
|
|
auto retained = row;
|
|
|
retained.sockets.first = static_cast<std::uint32_t>(socketWrite);
|
|
|
for (const auto& socket :
|
|
|
- std::span(sockets).subspan(row.sockets.first, row.sockets.count)) {
|
|
|
- sockets[socketWrite++] = socket;
|
|
|
+ std::span(sockets_).subspan(row.sockets.first, row.sockets.count)) {
|
|
|
+ sockets_[socketWrite++] = socket;
|
|
|
}
|
|
|
- entries[write++] = retained;
|
|
|
+ entries_[write++] = retained;
|
|
|
}
|
|
|
}
|
|
|
pool.entries.count = static_cast<std::uint32_t>(write) - pool.entries.first;
|
|
|
}
|
|
|
- entries.resize(write);
|
|
|
- sockets.resize(socketWrite);
|
|
|
- for (auto& item : items) {
|
|
|
- if (item.poolIndex != domain::kAbsent && item.poolIndex >= pools.size()) {
|
|
|
+ entries_.resize(write);
|
|
|
+ sockets_.resize(socketWrite);
|
|
|
+ for (auto& item : items_) {
|
|
|
+ if (item.poolIndex != domain::kAbsent && item.poolIndex >= pools_.size()) {
|
|
|
item = {};
|
|
|
}
|
|
|
}
|
|
|
return state::build_data::publish_reward_definitions(
|
|
|
- {pools, entries, items, instructions, modifiers, sockets});
|
|
|
+ {pools_, entries_, items_, instructions_, modifiers_, sockets_});
|
|
|
}
|
|
|
|
|
|
} // namespace sunrise::client::content::items::packages
|