mirror of
https://github.com/diasurgical/DevilutionX.git
synced 2026-10-11 22:29:54 +00:00
Replace tl::expected with std::expected
Now that the project targets C++23, use the standard library's std::expected instead of the vendored tl::expected polyfill: - tl::expected -> std::expected, tl::unexpected/tl::make_unexpected -> std::unexpected - .map()/.map_error() -> .transform()/.transform_error() - #include <expected.hpp> -> #include <expected>, grouped with std headers - Remove 3rdParty/tl/expected.hpp (the tl target remains for function_ref.hpp) Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
committed by
Anders Jenbo
co-authored by
Claude Fable 5
parent
c4fed8aeb6
commit
63e85d9b1b
Vendored
-2444
File diff suppressed because it is too large
Load Diff
+2
-3
@@ -8,6 +8,7 @@
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <expected>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_error.h>
|
||||
@@ -19,8 +20,6 @@
|
||||
#include "utils/sdl_compat.h"
|
||||
#endif
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#define DEVILUTIONX_SCREENSHOT_FORMAT_PCX 0
|
||||
#define DEVILUTIONX_SCREENSHOT_FORMAT_PNG 1
|
||||
|
||||
@@ -102,7 +101,7 @@ void CaptureScreen()
|
||||
system_palette = origSystemPalette;
|
||||
SystemPaletteUpdated();
|
||||
|
||||
const tl::expected<void, std::string> result =
|
||||
const std::expected<void, std::string> result =
|
||||
#if DEVILUTIONX_SCREENSHOT_FORMAT == DEVILUTIONX_SCREENSHOT_FORMAT_PCX
|
||||
WriteSurfaceToFilePcx(GlobalBackBuffer(), outStream);
|
||||
#elif DEVILUTIONX_SCREENSHOT_FORMAT == DEVILUTIONX_SCREENSHOT_FORMAT_PNG
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
@@ -18,8 +19,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "DiabloUI/text_input.hpp"
|
||||
#include "DiabloUI/ui_flags.hpp"
|
||||
#include "engine/displacement.hpp"
|
||||
@@ -94,7 +93,7 @@ void AddInfoBoxString(std::string &&str, bool floatingBox = false);
|
||||
void DrawPanelBox(const Surface &out, SDL_Rect srcRect, Point targetPosition);
|
||||
Point GetPanelPosition(UiPanels panel, Point offset = { 0, 0 });
|
||||
|
||||
tl::expected<void, std::string> InitMainPanel();
|
||||
std::expected<void, std::string> InitMainPanel();
|
||||
void DrawMainPanel(const Surface &out);
|
||||
|
||||
/**
|
||||
|
||||
@@ -353,7 +353,7 @@ void DrawPanelBox(const Surface &out, SDL_Rect srcRect, Point targetPosition)
|
||||
out.BlitFrom(*BottomBuffer, srcRect, targetPosition);
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> InitMainPanel()
|
||||
std::expected<void, std::string> InitMainPanel()
|
||||
{
|
||||
if (!HeadlessMode) {
|
||||
BottomBuffer.emplace(GetMainPanel().size.width, (GetMainPanel().size.height + PanelPaddingHeight) * (IsChatAvailable() ? 2 : 1));
|
||||
|
||||
+12
-12
@@ -3,10 +3,10 @@
|
||||
#include <bitset>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
|
||||
#include <expected.hpp>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "engine/assets.hpp"
|
||||
@@ -14,27 +14,27 @@
|
||||
#include "utils/language.h"
|
||||
|
||||
namespace devilution {
|
||||
tl::expected<DataFile, DataFile::Error> DataFile::load(std::string_view path)
|
||||
std::expected<DataFile, DataFile::Error> DataFile::load(std::string_view path)
|
||||
{
|
||||
AssetRef ref = FindAsset(path);
|
||||
if (!ref.ok())
|
||||
return tl::unexpected { Error::NotFound };
|
||||
return std::unexpected { Error::NotFound };
|
||||
const size_t size = ref.size();
|
||||
// TODO: It should be possible to stream the data file contents instead of copying the whole thing into memory
|
||||
std::unique_ptr<char[]> data { new char[size] };
|
||||
{
|
||||
AssetHandle handle = OpenIntegralAsset(std::move(ref));
|
||||
if (!handle.ok())
|
||||
return tl::unexpected { Error::OpenFailed };
|
||||
return std::unexpected { Error::OpenFailed };
|
||||
if (size > 0 && !handle.read(data.get(), size))
|
||||
return tl::unexpected { Error::BadRead };
|
||||
return std::unexpected { Error::BadRead };
|
||||
}
|
||||
return DataFile { std::move(data), size };
|
||||
}
|
||||
|
||||
DataFile DataFile::loadOrDie(std::string_view path)
|
||||
{
|
||||
tl::expected<DataFile, DataFile::Error> dataFileResult = DataFile::load(path);
|
||||
std::expected<DataFile, DataFile::Error> dataFileResult = DataFile::load(path);
|
||||
if (!dataFileResult.has_value()) {
|
||||
DataFile::reportFatalError(dataFileResult.error(), path);
|
||||
}
|
||||
@@ -92,7 +92,7 @@ void DataFile::reportFatalFieldError(DataFileField::Error code, std::string_view
|
||||
}
|
||||
}
|
||||
|
||||
tl::expected<void, DataFile::Error> DataFile::parseHeader(ColumnDefinition *begin, ColumnDefinition *end, tl::function_ref<tl::expected<uint8_t, ColumnDefinition::Error>(std::string_view)> mapper)
|
||||
std::expected<void, DataFile::Error> DataFile::parseHeader(ColumnDefinition *begin, ColumnDefinition *end, tl::function_ref<std::expected<uint8_t, ColumnDefinition::Error>(std::string_view)> mapper)
|
||||
{
|
||||
std::bitset<std::numeric_limits<uint8_t>::max()> seenColumns;
|
||||
unsigned lastColumn = 0;
|
||||
@@ -129,23 +129,23 @@ tl::expected<void, DataFile::Error> DataFile::parseHeader(ColumnDefinition *begi
|
||||
// Incrementing the iterator causes it to read to the end of the record in case we broke early (maybe there were extra columns)
|
||||
++firstRecord;
|
||||
if (firstRecord == this->end()) {
|
||||
return tl::unexpected { Error::NoContent };
|
||||
return std::unexpected { Error::NoContent };
|
||||
}
|
||||
|
||||
body_ = firstRecord.data();
|
||||
|
||||
if (begin != end) {
|
||||
return tl::unexpected { Error::NotEnoughColumns };
|
||||
return std::unexpected { Error::NotEnoughColumns };
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
tl::expected<void, DataFile::Error> DataFile::skipHeader()
|
||||
std::expected<void, DataFile::Error> DataFile::skipHeader()
|
||||
{
|
||||
RecordIterator it { data(), data() + size(), false };
|
||||
++it;
|
||||
if (it == this->end()) {
|
||||
return tl::unexpected { Error::NoContent };
|
||||
return std::unexpected { Error::NoContent };
|
||||
}
|
||||
body_ = it.data();
|
||||
return {};
|
||||
@@ -153,7 +153,7 @@ tl::expected<void, DataFile::Error> DataFile::skipHeader()
|
||||
|
||||
void DataFile::skipHeaderOrDie(std::string_view path)
|
||||
{
|
||||
if (tl::expected<void, DataFile::Error> result = skipHeader(); !result.has_value()) {
|
||||
if (std::expected<void, DataFile::Error> result = skipHeader(); !result.has_value()) {
|
||||
DataFile::reportFatalError(result.error(), path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <expected>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <string_view>
|
||||
|
||||
#include <expected.hpp>
|
||||
#include <function_ref.hpp>
|
||||
|
||||
#include "iterators.hpp"
|
||||
@@ -74,7 +74,7 @@ public:
|
||||
* @return an object containing an owned pointer to an in-memory copy of the file
|
||||
* or an error code describing the reason for failure.
|
||||
*/
|
||||
static tl::expected<DataFile, Error> load(std::string_view path);
|
||||
static std::expected<DataFile, Error> load(std::string_view path);
|
||||
|
||||
static DataFile loadOrDie(std::string_view path);
|
||||
|
||||
@@ -95,7 +95,7 @@ public:
|
||||
* @param mapper Function that maps from a string_view to a unique numeric identifier for the column
|
||||
* @return If the file ends after the header or not enough columns were defined this function returns an error code describing the failure.
|
||||
*/
|
||||
[[nodiscard]] tl::expected<void, DataFile::Error> parseHeader(ColumnDefinition *begin, ColumnDefinition *end, tl::function_ref<tl::expected<uint8_t, ColumnDefinition::Error>(std::string_view)> mapper);
|
||||
[[nodiscard]] std::expected<void, DataFile::Error> parseHeader(ColumnDefinition *begin, ColumnDefinition *end, tl::function_ref<std::expected<uint8_t, ColumnDefinition::Error>(std::string_view)> mapper);
|
||||
|
||||
/**
|
||||
* @brief Templated version of parseHeader(uint8_t) to allow using directly with enum definitions of columns
|
||||
@@ -106,12 +106,12 @@ public:
|
||||
* @return A void success result or an error code as described above
|
||||
*/
|
||||
template <typename T>
|
||||
[[nodiscard]] tl::expected<void, DataFile::Error> parseHeader(ColumnDefinition *begin, ColumnDefinition *end, std::function<tl::expected<T, ColumnDefinition::Error>(std::string_view)> typedMapper)
|
||||
[[nodiscard]] std::expected<void, DataFile::Error> parseHeader(ColumnDefinition *begin, ColumnDefinition *end, std::function<std::expected<T, ColumnDefinition::Error>(std::string_view)> typedMapper)
|
||||
{
|
||||
return parseHeader(begin, end, [typedMapper](std::string_view label) { return typedMapper(label).transform([](T value) { return static_cast<uint8_t>(value); }); });
|
||||
}
|
||||
|
||||
[[nodiscard]] tl::expected<void, DataFile::Error> skipHeader();
|
||||
[[nodiscard]] std::expected<void, DataFile::Error> skipHeader();
|
||||
|
||||
void skipHeaderOrDie(std::string_view path);
|
||||
|
||||
|
||||
+30
-31
@@ -1,11 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <charconv>
|
||||
#include <expected>
|
||||
#include <optional>
|
||||
#include <ostream>
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "parser.hpp"
|
||||
#include "utils/parse_int.hpp"
|
||||
#include "utils/str_cat.hpp"
|
||||
@@ -26,29 +25,29 @@ public:
|
||||
InvalidValue
|
||||
};
|
||||
|
||||
static tl::expected<void, Error> mapError(std::errc ec)
|
||||
static std::expected<void, Error> mapError(std::errc ec)
|
||||
{
|
||||
if (ec == std::errc())
|
||||
return {};
|
||||
switch (ec) {
|
||||
case std::errc::result_out_of_range:
|
||||
return tl::unexpected { Error::OutOfRange };
|
||||
return std::unexpected { Error::OutOfRange };
|
||||
case std::errc::invalid_argument:
|
||||
return tl::unexpected { Error::NotANumber };
|
||||
return std::unexpected { Error::NotANumber };
|
||||
default:
|
||||
return tl::unexpected { Error::InvalidValue };
|
||||
return std::unexpected { Error::InvalidValue };
|
||||
}
|
||||
}
|
||||
|
||||
static tl::expected<void, Error> mapError(ParseIntError ec)
|
||||
static std::expected<void, Error> mapError(ParseIntError ec)
|
||||
{
|
||||
switch (ec) {
|
||||
case ParseIntError::OutOfRange:
|
||||
return tl::unexpected { Error::OutOfRange };
|
||||
return std::unexpected { Error::OutOfRange };
|
||||
case ParseIntError::ParseError:
|
||||
return tl::unexpected { Error::NotANumber };
|
||||
return std::unexpected { Error::NotANumber };
|
||||
default:
|
||||
return tl::unexpected { Error::InvalidValue };
|
||||
return std::unexpected { Error::InvalidValue };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +94,7 @@ public:
|
||||
* @return an error code corresponding to the from_chars result if parsing failed
|
||||
*/
|
||||
template <typename T>
|
||||
[[nodiscard]] tl::expected<void, Error> parseInt(T &destination)
|
||||
[[nodiscard]] std::expected<void, Error> parseInt(T &destination)
|
||||
{
|
||||
std::from_chars_result result {};
|
||||
if (state_->status == GetFieldResult::Status::ReadyToRead) {
|
||||
@@ -114,7 +113,7 @@ public:
|
||||
return mapError(result.ec);
|
||||
}
|
||||
|
||||
[[nodiscard]] tl::expected<void, Error> parseBool(bool &destination)
|
||||
[[nodiscard]] std::expected<void, Error> parseBool(bool &destination)
|
||||
{
|
||||
const std::string_view str = value();
|
||||
if (str == "true") {
|
||||
@@ -125,16 +124,16 @@ public:
|
||||
destination = false;
|
||||
return {};
|
||||
}
|
||||
return tl::make_unexpected(DataFileField::Error::InvalidValue);
|
||||
return std::unexpected(DataFileField::Error::InvalidValue);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] tl::expected<void, Error> parseIntArray(T *destination, size_t n)
|
||||
[[nodiscard]] std::expected<void, Error> parseIntArray(T *destination, size_t n)
|
||||
{
|
||||
size_t i = 0;
|
||||
for (const std::string_view part : SplitByChar(value(), ',')) {
|
||||
if (i == n)
|
||||
return tl::make_unexpected(Error::InvalidValue);
|
||||
return std::unexpected(Error::InvalidValue);
|
||||
const std::from_chars_result result
|
||||
= std::from_chars(part.data(), part.data() + part.size(), destination[i]);
|
||||
if (result.ec != std::errc())
|
||||
@@ -142,41 +141,41 @@ public:
|
||||
++i;
|
||||
}
|
||||
if (i != n)
|
||||
return tl::make_unexpected(Error::InvalidValue);
|
||||
return std::unexpected(Error::InvalidValue);
|
||||
return {};
|
||||
}
|
||||
|
||||
template <typename T, size_t N>
|
||||
[[nodiscard]] tl::expected<void, Error> parseIntArray(T (&destination)[N])
|
||||
[[nodiscard]] std::expected<void, Error> parseIntArray(T (&destination)[N])
|
||||
{
|
||||
return parseIntArray<T>(destination, N);
|
||||
}
|
||||
|
||||
template <typename T, size_t N>
|
||||
[[nodiscard]] tl::expected<void, Error> parseIntArray(std::array<T, N> &destination)
|
||||
[[nodiscard]] std::expected<void, Error> parseIntArray(std::array<T, N> &destination)
|
||||
{
|
||||
return parseIntArray<T>(destination.data(), N);
|
||||
}
|
||||
|
||||
template <typename T, typename ParseFn>
|
||||
[[nodiscard]] tl::expected<void, std::string> parseEnumArray(T *destination, size_t n, std::optional<T> fillMissing, ParseFn &&parseFn)
|
||||
[[nodiscard]] std::expected<void, std::string> parseEnumArray(T *destination, size_t n, std::optional<T> fillMissing, ParseFn &&parseFn)
|
||||
{
|
||||
size_t i = 0;
|
||||
const std::string_view str = value();
|
||||
if (!str.empty()) {
|
||||
for (const std::string_view part : SplitByChar(str, ',')) {
|
||||
if (i == n)
|
||||
return tl::make_unexpected(StrCat("Too many values, max: ", n));
|
||||
return std::unexpected(StrCat("Too many values, max: ", n));
|
||||
auto result = parseFn(part);
|
||||
if (!result.has_value()) {
|
||||
return tl::make_unexpected(std::move(result).error());
|
||||
return std::unexpected(std::move(result).error());
|
||||
}
|
||||
destination[i++] = *result;
|
||||
}
|
||||
}
|
||||
if (i != n) {
|
||||
if (!fillMissing.has_value()) {
|
||||
return tl::make_unexpected(StrCat("Too few values, expected ", n, " got ", i));
|
||||
return std::unexpected(StrCat("Too few values, expected ", n, " got ", i));
|
||||
}
|
||||
while (i < n) {
|
||||
destination[i++] = *fillMissing;
|
||||
@@ -186,19 +185,19 @@ public:
|
||||
}
|
||||
|
||||
template <typename T, size_t N, typename ParseFn>
|
||||
[[nodiscard]] tl::expected<void, std::string> parseEnumArray(T (&destination)[N], std::optional<T> fillMissing, ParseFn &&parseFn)
|
||||
[[nodiscard]] std::expected<void, std::string> parseEnumArray(T (&destination)[N], std::optional<T> fillMissing, ParseFn &&parseFn)
|
||||
{
|
||||
return parseEnumArray<T, ParseFn>(destination, N, std::move(fillMissing), std::forward<ParseFn>(parseFn));
|
||||
}
|
||||
|
||||
template <typename T, size_t N, typename ParseFn>
|
||||
[[nodiscard]] tl::expected<void, std::string> parseIntArray(std::array<T, N> &destination, std::optional<T> fillMissing, ParseFn &&parseFn)
|
||||
[[nodiscard]] std::expected<void, std::string> parseIntArray(std::array<T, N> &destination, std::optional<T> fillMissing, ParseFn &&parseFn)
|
||||
{
|
||||
return parseEnumArray<T, ParseFn>(destination.data(), N, std::move(fillMissing), std::forward<ParseFn>(parseFn));
|
||||
}
|
||||
|
||||
template <typename T, typename ParseFn>
|
||||
[[nodiscard]] tl::expected<void, std::string> parseEnumList(T &destination, ParseFn &&parseFn)
|
||||
[[nodiscard]] std::expected<void, std::string> parseEnumList(T &destination, ParseFn &&parseFn)
|
||||
{
|
||||
destination = {};
|
||||
const std::string_view str = value();
|
||||
@@ -207,17 +206,17 @@ public:
|
||||
for (const std::string_view part : SplitByChar(str, ',')) {
|
||||
auto result = parseFn(part);
|
||||
if (!result.has_value())
|
||||
return tl::make_unexpected(std::move(result).error());
|
||||
return std::unexpected(std::move(result).error());
|
||||
destination |= result.value();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] tl::expected<T, Error> asInt()
|
||||
[[nodiscard]] std::expected<T, Error> asInt()
|
||||
{
|
||||
T value = 0;
|
||||
return parseInt(value).map([value]() { return value; });
|
||||
return parseInt(value).transform([value]() { return value; });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -231,7 +230,7 @@ public:
|
||||
* @return an error code equivalent to what you'd get from from_chars if parsing failed
|
||||
*/
|
||||
template <typename T>
|
||||
[[nodiscard]] tl::expected<void, Error> parseFixed6(T &destination)
|
||||
[[nodiscard]] std::expected<void, Error> parseFixed6(T &destination)
|
||||
{
|
||||
ParseIntResult<T> parseResult;
|
||||
if (state_->status == GetFieldResult::Status::ReadyToRead) {
|
||||
@@ -255,10 +254,10 @@ public:
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] tl::expected<T, Error> asFixed6()
|
||||
[[nodiscard]] std::expected<T, Error> asFixed6()
|
||||
{
|
||||
T value = 0;
|
||||
return parseFixed6(value).map([value]() { return value; });
|
||||
return parseFixed6(value).transform([value]() { return value; });
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <expected>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
|
||||
#include <expected.hpp>
|
||||
#include <function_ref.hpp>
|
||||
|
||||
#include "data/file.hpp"
|
||||
@@ -86,7 +86,7 @@ public:
|
||||
void read(std::string_view name, T &out, F &&parseFn)
|
||||
{
|
||||
DataFileField field = nextField();
|
||||
tl::expected<T, std::string> result = parseFn(field.value());
|
||||
std::expected<T, std::string> result = parseFn(field.value());
|
||||
failOnError(result, name, field, DataFileField::Error::InvalidValue);
|
||||
out = *std::move(result);
|
||||
}
|
||||
@@ -116,7 +116,7 @@ public:
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
void failOnError(const tl::expected<T, DataFileField::Error> &result, std::string_view name, const DataFileField &field)
|
||||
void failOnError(const std::expected<T, DataFileField::Error> &result, std::string_view name, const DataFileField &field)
|
||||
{
|
||||
if (!result.has_value()) {
|
||||
DataFile::reportFatalFieldError(result.error(), filename_, name, field);
|
||||
@@ -124,7 +124,7 @@ private:
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void failOnError(const tl::expected<T, std::string> &result, std::string_view name, const DataFileField &field, DataFileField::Error error)
|
||||
void failOnError(const std::expected<T, std::string> &result, std::string_view name, const DataFileField &field, DataFileField::Error error)
|
||||
{
|
||||
if (!result.has_value()) {
|
||||
DataFile::reportFatalFieldError(error, filename_, name, field, result.error());
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <expected>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
|
||||
#include <expected.hpp>
|
||||
#include <function_ref.hpp>
|
||||
|
||||
#include "data/file.hpp"
|
||||
@@ -25,7 +25,7 @@ public:
|
||||
void readValue(std::string_view expectedKey, T &outValue, F &&readFn)
|
||||
{
|
||||
DataFileField valueField = getValueField(expectedKey);
|
||||
if (const tl::expected<void, devilution::DataFileField::Error> result = readFn(valueField, outValue);
|
||||
if (const std::expected<void, devilution::DataFileField::Error> result = readFn(valueField, outValue);
|
||||
!result.has_value()) {
|
||||
DataFile::reportFatalFieldError(result.error(), filename_, "Value", valueField);
|
||||
}
|
||||
@@ -35,10 +35,10 @@ public:
|
||||
template <typename T, typename F>
|
||||
void read(std::string_view expectedKey, T &outValue, F &&parseFn)
|
||||
{
|
||||
readValue(expectedKey, outValue, [&parseFn](DataFileField &valueField, T &outValue) -> tl::expected<void, devilution::DataFileField::Error> {
|
||||
readValue(expectedKey, outValue, [&parseFn](DataFileField &valueField, T &outValue) -> std::expected<void, devilution::DataFileField::Error> {
|
||||
const auto result = parseFn(valueField.value());
|
||||
if (!result.has_value()) {
|
||||
return tl::make_unexpected(devilution::DataFileField::Error::InvalidValue);
|
||||
return std::unexpected(devilution::DataFileField::Error::InvalidValue);
|
||||
}
|
||||
|
||||
outValue = result.value();
|
||||
@@ -49,10 +49,10 @@ public:
|
||||
template <typename T, typename F>
|
||||
void readEnumList(std::string_view expectedKey, T &outValue, F &&parseFn)
|
||||
{
|
||||
readValue(expectedKey, outValue, [&parseFn](DataFileField &valueField, T &outValue) -> tl::expected<void, devilution::DataFileField::Error> {
|
||||
readValue(expectedKey, outValue, [&parseFn](DataFileField &valueField, T &outValue) -> std::expected<void, devilution::DataFileField::Error> {
|
||||
const auto result = valueField.parseEnumList(outValue, std::forward<F>(parseFn));
|
||||
if (!result.has_value()) {
|
||||
return tl::make_unexpected(devilution::DataFileField::Error::InvalidValue);
|
||||
return std::unexpected(devilution::DataFileField::Error::InvalidValue);
|
||||
}
|
||||
|
||||
return {};
|
||||
@@ -81,15 +81,15 @@ public:
|
||||
{
|
||||
readValue(expectedKey, outValue, [](DataFileField &valueField, std::string &outValue) {
|
||||
outValue = valueField.value();
|
||||
return tl::expected<void, devilution::DataFileField::Error> {};
|
||||
return std::expected<void, devilution::DataFileField::Error> {};
|
||||
});
|
||||
}
|
||||
|
||||
void readChar(std::string_view expectedKey, char &outValue)
|
||||
{
|
||||
readValue(expectedKey, outValue, [](DataFileField &valueField, char &outValue) -> tl::expected<void, devilution::DataFileField::Error> {
|
||||
readValue(expectedKey, outValue, [](DataFileField &valueField, char &outValue) -> std::expected<void, devilution::DataFileField::Error> {
|
||||
if (valueField.value().size() != 1) {
|
||||
return tl::make_unexpected(devilution::DataFileField::Error::InvalidValue);
|
||||
return std::unexpected(devilution::DataFileField::Error::InvalidValue);
|
||||
}
|
||||
|
||||
outValue = valueField.value().at(0);
|
||||
|
||||
+9
-9
@@ -1360,12 +1360,12 @@ void DiabloDeinit()
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> LoadLvlGFX()
|
||||
std::expected<void, std::string> LoadLvlGFX()
|
||||
{
|
||||
assert(pDungeonCels == nullptr);
|
||||
constexpr int SpecialCelWidth = 64;
|
||||
|
||||
const auto loadAll = [](const char *cel, const char *til, const char *special) -> tl::expected<void, std::string> {
|
||||
const auto loadAll = [](const char *cel, const char *til, const char *special) -> std::expected<void, std::string> {
|
||||
ASSIGN_OR_RETURN(pDungeonCels, LoadFileInMemWithStatus(cel));
|
||||
ASSIGN_OR_RETURN(pMegaTiles, LoadFileInMemWithStatus<MegaTile>(til));
|
||||
ASSIGN_OR_RETURN(pSpecialCels, LoadCelWithStatus(special, SpecialCelWidth));
|
||||
@@ -1420,11 +1420,11 @@ tl::expected<void, std::string> LoadLvlGFX()
|
||||
"nlevels\\l5data\\l5.til",
|
||||
"nlevels\\l5data\\l5s");
|
||||
default:
|
||||
return tl::make_unexpected("LoadLvlGFX");
|
||||
return std::unexpected("LoadLvlGFX");
|
||||
}
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> LoadAllGFX()
|
||||
std::expected<void, std::string> LoadAllGFX()
|
||||
{
|
||||
IncProgress();
|
||||
#if !defined(USE_SDL1) && !defined(__vita__)
|
||||
@@ -3136,7 +3136,7 @@ void LoadGameLevelStash()
|
||||
gbIsHellfireSaveGame = isHellfireSaveGame;
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> LoadGameLevelDungeon(bool firstflag, lvl_entry lvldir, const Player &myPlayer)
|
||||
std::expected<void, std::string> LoadGameLevelDungeon(bool firstflag, lvl_entry lvldir, const Player &myPlayer)
|
||||
{
|
||||
if (firstflag || lvldir == ENTRY_LOAD || !myPlayer._pLvlVisited[currlevel] || gbIsMultiplayer) {
|
||||
HoldThemeRooms();
|
||||
@@ -3232,7 +3232,7 @@ void LoadGameLevelSetVisited()
|
||||
}
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> LoadGameLevelTown(bool firstflag, lvl_entry lvldir, const Player &myPlayer)
|
||||
std::expected<void, std::string> LoadGameLevelTown(bool firstflag, lvl_entry lvldir, const Player &myPlayer)
|
||||
{
|
||||
for (int i = 0; i < MAXDUNX; i++) { // NOLINT(modernize-loop-convert)
|
||||
for (int j = 0; j < MAXDUNY; j++) {
|
||||
@@ -3261,7 +3261,7 @@ tl::expected<void, std::string> LoadGameLevelTown(bool firstflag, lvl_entry lvld
|
||||
return {};
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> LoadGameLevelSetLevel(bool firstflag, lvl_entry lvldir, const Player &myPlayer)
|
||||
std::expected<void, std::string> LoadGameLevelSetLevel(bool firstflag, lvl_entry lvldir, const Player &myPlayer)
|
||||
{
|
||||
LoadSetMap();
|
||||
IncProgress();
|
||||
@@ -3313,7 +3313,7 @@ tl::expected<void, std::string> LoadGameLevelSetLevel(bool firstflag, lvl_entry
|
||||
return {};
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> LoadGameLevelStandardLevel(bool firstflag, lvl_entry lvldir, const Player &myPlayer)
|
||||
std::expected<void, std::string> LoadGameLevelStandardLevel(bool firstflag, lvl_entry lvldir, const Player &myPlayer)
|
||||
{
|
||||
CreateLevel(lvldir);
|
||||
|
||||
@@ -3396,7 +3396,7 @@ void LoadGameLevelCalculateCursor()
|
||||
CheckCursMove();
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> LoadGameLevel(bool firstflag, lvl_entry lvldir)
|
||||
std::expected<void, std::string> LoadGameLevel(bool firstflag, lvl_entry lvldir)
|
||||
{
|
||||
const _music_id neededTrack = GetLevelMusic(leveltype);
|
||||
|
||||
|
||||
+1
-1
@@ -106,7 +106,7 @@ void diablo_focus_pause();
|
||||
void diablo_focus_unpause();
|
||||
bool PressEscKey();
|
||||
void DisableInputEventHandler(const SDL_Event &event, uint16_t modState);
|
||||
tl::expected<void, std::string> LoadGameLevel(bool firstflag, lvl_entry lvldir);
|
||||
std::expected<void, std::string> LoadGameLevel(bool firstflag, lvl_entry lvldir);
|
||||
bool IsDiabloAlive(bool playSFX);
|
||||
void PrintScreen(SDL_Keycode vkey);
|
||||
|
||||
|
||||
+39
-40
@@ -3,6 +3,7 @@
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <expected>
|
||||
#include <memory>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
@@ -11,8 +12,6 @@
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "player.h"
|
||||
|
||||
namespace devilution {
|
||||
@@ -20,7 +19,7 @@ namespace net {
|
||||
|
||||
void base::process_network_packets()
|
||||
{
|
||||
tl::expected<void, PacketError> result = poll();
|
||||
std::expected<void, PacketError> result = poll();
|
||||
if (!result.has_value()) {
|
||||
LogVerbose("Error polling network: {}", result.error().what());
|
||||
}
|
||||
@@ -61,7 +60,7 @@ void base::DisconnectNet(plr_t plr)
|
||||
{
|
||||
}
|
||||
|
||||
tl::expected<void, PacketError> base::SendEchoRequest(plr_t player)
|
||||
std::expected<void, PacketError> base::SendEchoRequest(plr_t player)
|
||||
{
|
||||
if (plr_self == PLR_BROADCAST)
|
||||
return {};
|
||||
@@ -69,29 +68,29 @@ tl::expected<void, PacketError> base::SendEchoRequest(plr_t player)
|
||||
return {};
|
||||
|
||||
const timestamp_t now = SDL_GetTicks();
|
||||
tl::expected<std::unique_ptr<packet>, PacketError> pkt
|
||||
std::expected<std::unique_ptr<packet>, PacketError> pkt
|
||||
= pktfty->make_packet<PT_ECHO_REQUEST>(plr_self, player, now);
|
||||
if (!pkt.has_value()) {
|
||||
return tl::make_unexpected(pkt.error());
|
||||
return std::unexpected(pkt.error());
|
||||
}
|
||||
return send(**pkt);
|
||||
}
|
||||
|
||||
tl::expected<void, PacketError> base::HandleAccept(packet &pkt)
|
||||
std::expected<void, PacketError> base::HandleAccept(packet &pkt)
|
||||
{
|
||||
if (plr_self != PLR_BROADCAST) {
|
||||
return {}; // already have player id
|
||||
}
|
||||
if (pkt.Cookie() == cookie_self) {
|
||||
tl::expected<plr_t, PacketError> newPlayerPkt = pkt.NewPlayer();
|
||||
std::expected<plr_t, PacketError> newPlayerPkt = pkt.NewPlayer();
|
||||
if (!newPlayerPkt.has_value())
|
||||
return tl::make_unexpected(newPlayerPkt.error());
|
||||
return std::unexpected(newPlayerPkt.error());
|
||||
plr_self = *std::move(newPlayerPkt);
|
||||
Connect(plr_self);
|
||||
}
|
||||
tl::expected<const buffer_t *, PacketError> infoPkt = pkt.Info();
|
||||
std::expected<const buffer_t *, PacketError> infoPkt = pkt.Info();
|
||||
if (!infoPkt.has_value())
|
||||
return tl::make_unexpected(infoPkt.error());
|
||||
return std::unexpected(infoPkt.error());
|
||||
const buffer_t &info = **infoPkt;
|
||||
if (game_init_info != info) {
|
||||
if (info.size() != sizeof(GameData)) {
|
||||
@@ -109,14 +108,14 @@ tl::expected<void, PacketError> base::HandleAccept(packet &pkt)
|
||||
return {};
|
||||
}
|
||||
|
||||
tl::expected<void, PacketError> base::HandleConnect(packet &pkt)
|
||||
std::expected<void, PacketError> base::HandleConnect(packet &pkt)
|
||||
{
|
||||
return pkt.NewPlayer().transform([this](plr_t &&newPlayer) {
|
||||
Connect(newPlayer);
|
||||
});
|
||||
}
|
||||
|
||||
tl::expected<void, PacketError> base::HandleTurn(packet &pkt)
|
||||
std::expected<void, PacketError> base::HandleTurn(packet &pkt)
|
||||
{
|
||||
const plr_t src = pkt.Source();
|
||||
PlayerState &playerState = playerStateTable_[src];
|
||||
@@ -127,17 +126,17 @@ tl::expected<void, PacketError> base::HandleTurn(packet &pkt)
|
||||
});
|
||||
}
|
||||
|
||||
tl::expected<void, PacketError> base::HandleDisconnect(packet &pkt)
|
||||
std::expected<void, PacketError> base::HandleDisconnect(packet &pkt)
|
||||
{
|
||||
tl::expected<plr_t, PacketError> newPlayer = pkt.NewPlayer();
|
||||
std::expected<plr_t, PacketError> newPlayer = pkt.NewPlayer();
|
||||
if (!newPlayer.has_value())
|
||||
return tl::make_unexpected(newPlayer.error());
|
||||
return std::unexpected(newPlayer.error());
|
||||
if (*newPlayer == plr_self)
|
||||
return tl::make_unexpected("We were dropped by the owner?");
|
||||
return std::unexpected("We were dropped by the owner?");
|
||||
if (IsConnected(*newPlayer)) {
|
||||
tl::expected<leaveinfo_t, PacketError> leaveinfo = pkt.LeaveInfo();
|
||||
std::expected<leaveinfo_t, PacketError> leaveinfo = pkt.LeaveInfo();
|
||||
if (!leaveinfo.has_value())
|
||||
return tl::make_unexpected(leaveinfo.error());
|
||||
return std::unexpected(leaveinfo.error());
|
||||
_SNETEVENT ev;
|
||||
ev.eventid = EVENT_TYPE_PLAYER_LEAVE_GAME;
|
||||
ev.playerid = *newPlayer;
|
||||
@@ -153,7 +152,7 @@ tl::expected<void, PacketError> base::HandleDisconnect(packet &pkt)
|
||||
return {};
|
||||
}
|
||||
|
||||
tl::expected<void, PacketError> base::HandleEchoRequest(packet &pkt)
|
||||
std::expected<void, PacketError> base::HandleEchoRequest(packet &pkt)
|
||||
{
|
||||
// If we have already left the game,
|
||||
// there is no need to respond to echoes
|
||||
@@ -168,7 +167,7 @@ tl::expected<void, PacketError> base::HandleEchoRequest(packet &pkt)
|
||||
});
|
||||
}
|
||||
|
||||
tl::expected<void, PacketError> base::HandleEchoReply(packet &pkt)
|
||||
std::expected<void, PacketError> base::HandleEchoReply(packet &pkt)
|
||||
{
|
||||
const uint32_t now = SDL_GetTicks();
|
||||
plr_t src = pkt.Source();
|
||||
@@ -189,7 +188,7 @@ void base::ClearMsg(plr_t plr)
|
||||
message_queue.end());
|
||||
}
|
||||
|
||||
tl::expected<void, PacketError> base::Connect(plr_t player)
|
||||
std::expected<void, PacketError> base::Connect(plr_t player)
|
||||
{
|
||||
PlayerState &playerState = playerStateTable_[player];
|
||||
const bool wasConnected = playerState.isConnected;
|
||||
@@ -206,10 +205,10 @@ bool base::IsConnected(plr_t player) const
|
||||
return playerState.isConnected;
|
||||
}
|
||||
|
||||
tl::expected<void, PacketError> base::RecvLocal(packet &pkt)
|
||||
std::expected<void, PacketError> base::RecvLocal(packet &pkt)
|
||||
{
|
||||
if (pkt.Source() < MAX_PLRS) {
|
||||
if (tl::expected<void, PacketError> result = Connect(pkt.Source());
|
||||
if (std::expected<void, PacketError> result = Connect(pkt.Source());
|
||||
!result.has_value()) {
|
||||
return result;
|
||||
}
|
||||
@@ -271,13 +270,13 @@ bool base::SNetSendMessage(uint8_t playerId, void *data, size_t size)
|
||||
else
|
||||
dest = playerId;
|
||||
if (dest != plr_self) {
|
||||
tl::expected<std::unique_ptr<packet>, PacketError> pkt
|
||||
std::expected<std::unique_ptr<packet>, PacketError> pkt
|
||||
= pktfty->make_packet<PT_MESSAGE>(plr_self, dest, message);
|
||||
if (!pkt.has_value()) {
|
||||
LogError("make_packet: {}", pkt.error().what());
|
||||
return false;
|
||||
}
|
||||
tl::expected<void, PacketError> result = send(**pkt);
|
||||
std::expected<void, PacketError> result = send(**pkt);
|
||||
if (!result.has_value()) {
|
||||
LogError("send: {}", result.error().what());
|
||||
return false;
|
||||
@@ -384,23 +383,23 @@ bool base::SNetSendTurn(char *data, size_t size)
|
||||
return true;
|
||||
}
|
||||
|
||||
tl::expected<void, PacketError> base::SendTurnIfReady(turn_t turn)
|
||||
std::expected<void, PacketError> base::SendTurnIfReady(turn_t turn)
|
||||
{
|
||||
if (awaitingSequenceNumber_)
|
||||
awaitingSequenceNumber_ = !IsGameHost();
|
||||
|
||||
if (!awaitingSequenceNumber_) {
|
||||
tl::expected<std::unique_ptr<packet>, PacketError> pkt
|
||||
std::expected<std::unique_ptr<packet>, PacketError> pkt
|
||||
= pktfty->make_packet<PT_TURN>(plr_self, PLR_BROADCAST, turn);
|
||||
if (!pkt.has_value()) {
|
||||
return tl::make_unexpected(pkt.error());
|
||||
return std::unexpected(pkt.error());
|
||||
}
|
||||
return send(**pkt);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
tl::expected<void, PacketError> base::SendFirstTurnIfReady(plr_t player)
|
||||
std::expected<void, PacketError> base::SendFirstTurnIfReady(plr_t player)
|
||||
{
|
||||
if (awaitingSequenceNumber_)
|
||||
return {};
|
||||
@@ -411,12 +410,12 @@ tl::expected<void, PacketError> base::SendFirstTurnIfReady(plr_t player)
|
||||
return {};
|
||||
|
||||
for (const turn_t turn : turnQueue) {
|
||||
tl::expected<std::unique_ptr<packet>, PacketError> pkt
|
||||
std::expected<std::unique_ptr<packet>, PacketError> pkt
|
||||
= pktfty->make_packet<PT_TURN>(plr_self, player, turn);
|
||||
if (!pkt.has_value()) {
|
||||
return tl::make_unexpected(pkt.error());
|
||||
return std::unexpected(pkt.error());
|
||||
}
|
||||
tl::expected<void, PacketError> result = send(**pkt);
|
||||
std::expected<void, PacketError> result = send(**pkt);
|
||||
if (!result.has_value()) {
|
||||
return result;
|
||||
}
|
||||
@@ -424,7 +423,7 @@ tl::expected<void, PacketError> base::SendFirstTurnIfReady(plr_t player)
|
||||
return {};
|
||||
}
|
||||
|
||||
tl::expected<void, PacketError> base::MakeReady(seq_t sequenceNumber)
|
||||
std::expected<void, PacketError> base::MakeReady(seq_t sequenceNumber)
|
||||
{
|
||||
if (!awaitingSequenceNumber_)
|
||||
return {};
|
||||
@@ -438,7 +437,7 @@ tl::expected<void, PacketError> base::MakeReady(seq_t sequenceNumber)
|
||||
for (turn_t &turn : turnQueue) {
|
||||
turn.SequenceNumber = next_turn;
|
||||
next_turn++;
|
||||
if (tl::expected<void, PacketError> result = SendTurnIfReady(turn);
|
||||
if (std::expected<void, PacketError> result = SendTurnIfReady(turn);
|
||||
!result.has_value()) {
|
||||
return result;
|
||||
}
|
||||
@@ -482,14 +481,14 @@ bool base::SNetRegisterEventHandler(event_type evtype, SEVTHANDLER func)
|
||||
|
||||
bool base::SNetLeaveGame(net::leaveinfo_t type)
|
||||
{
|
||||
tl::expected<std::unique_ptr<packet>, PacketError> pkt
|
||||
std::expected<std::unique_ptr<packet>, PacketError> pkt
|
||||
= pktfty->make_packet<PT_DISCONNECT>(
|
||||
plr_self, PLR_BROADCAST, plr_self, type);
|
||||
if (!pkt.has_value()) {
|
||||
LogError("make_packet: {}", pkt.error().what());
|
||||
return false;
|
||||
}
|
||||
tl::expected<void, PacketError> result = send(**pkt);
|
||||
std::expected<void, PacketError> result = send(**pkt);
|
||||
if (!result.has_value()) {
|
||||
LogError("send: {}", result.error().what());
|
||||
return false;
|
||||
@@ -501,7 +500,7 @@ bool base::SNetLeaveGame(net::leaveinfo_t type)
|
||||
bool base::SNetDropPlayer(int playerid, net::leaveinfo_t flags)
|
||||
{
|
||||
const auto plr = static_cast<plr_t>(playerid);
|
||||
tl::expected<std::unique_ptr<packet>, PacketError> pkt
|
||||
std::expected<std::unique_ptr<packet>, PacketError> pkt
|
||||
= pktfty->make_packet<PT_DISCONNECT>(
|
||||
plr_self,
|
||||
PLR_BROADCAST,
|
||||
@@ -514,12 +513,12 @@ bool base::SNetDropPlayer(int playerid, net::leaveinfo_t flags)
|
||||
// Disconnect at the network layer first so we
|
||||
// don't send players their own disconnect packet
|
||||
DisconnectNet(plr);
|
||||
tl::expected<void, PacketError> sendResult = send(**pkt);
|
||||
std::expected<void, PacketError> sendResult = send(**pkt);
|
||||
if (!sendResult.has_value()) {
|
||||
LogError("send: {}", sendResult.error().what());
|
||||
return false;
|
||||
}
|
||||
tl::expected<void, PacketError> receiveResult = RecvLocal(**pkt);
|
||||
std::expected<void, PacketError> receiveResult = RecvLocal(**pkt);
|
||||
if (!receiveResult.has_value()) {
|
||||
LogError("SNetDropPlayer: {}", receiveResult.error().what());
|
||||
return false;
|
||||
|
||||
+14
-14
@@ -30,8 +30,8 @@ public:
|
||||
bool SNetGetOwnerTurnsWaiting(uint32_t *turns) override;
|
||||
bool SNetGetTurnsInTransit(uint32_t *turns) override;
|
||||
|
||||
virtual tl::expected<void, PacketError> poll() = 0;
|
||||
virtual tl::expected<void, PacketError> send(packet &pkt) = 0;
|
||||
virtual std::expected<void, PacketError> poll() = 0;
|
||||
virtual std::expected<void, PacketError> send(packet &pkt) = 0;
|
||||
virtual void DisconnectNet(plr_t plr);
|
||||
|
||||
void process_network_packets() override;
|
||||
@@ -81,10 +81,10 @@ protected:
|
||||
|
||||
std::unique_ptr<packet_factory> pktfty;
|
||||
|
||||
tl::expected<void, PacketError> Connect(plr_t player);
|
||||
tl::expected<void, PacketError> RecvLocal(packet &pkt);
|
||||
std::expected<void, PacketError> Connect(plr_t player);
|
||||
std::expected<void, PacketError> RecvLocal(packet &pkt);
|
||||
void RunEventHandler(_SNETEVENT &ev);
|
||||
tl::expected<void, PacketError> SendEchoRequest(plr_t player);
|
||||
std::expected<void, PacketError> SendEchoRequest(plr_t player);
|
||||
|
||||
[[nodiscard]] bool IsConnected(plr_t player) const;
|
||||
virtual bool IsGameHost() = 0;
|
||||
@@ -96,17 +96,17 @@ private:
|
||||
|
||||
plr_t GetOwner();
|
||||
bool AllTurnsArrived();
|
||||
tl::expected<void, PacketError> MakeReady(seq_t sequenceNumber);
|
||||
tl::expected<void, PacketError> SendTurnIfReady(turn_t turn);
|
||||
tl::expected<void, PacketError> SendFirstTurnIfReady(plr_t player);
|
||||
std::expected<void, PacketError> MakeReady(seq_t sequenceNumber);
|
||||
std::expected<void, PacketError> SendTurnIfReady(turn_t turn);
|
||||
std::expected<void, PacketError> SendFirstTurnIfReady(plr_t player);
|
||||
void ClearMsg(plr_t plr);
|
||||
|
||||
tl::expected<void, PacketError> HandleAccept(packet &pkt);
|
||||
tl::expected<void, PacketError> HandleConnect(packet &pkt);
|
||||
tl::expected<void, PacketError> HandleTurn(packet &pkt);
|
||||
tl::expected<void, PacketError> HandleDisconnect(packet &pkt);
|
||||
tl::expected<void, PacketError> HandleEchoRequest(packet &pkt);
|
||||
tl::expected<void, PacketError> HandleEchoReply(packet &pkt);
|
||||
std::expected<void, PacketError> HandleAccept(packet &pkt);
|
||||
std::expected<void, PacketError> HandleConnect(packet &pkt);
|
||||
std::expected<void, PacketError> HandleTurn(packet &pkt);
|
||||
std::expected<void, PacketError> HandleDisconnect(packet &pkt);
|
||||
std::expected<void, PacketError> HandleEchoRequest(packet &pkt);
|
||||
std::expected<void, PacketError> HandleEchoReply(packet &pkt);
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
|
||||
@@ -27,8 +27,8 @@ class base_protocol : public base {
|
||||
public:
|
||||
int create(std::string_view addrstr) override;
|
||||
int join(std::string_view addrstr) override;
|
||||
tl::expected<void, PacketError> poll() override;
|
||||
tl::expected<void, PacketError> send(packet &pkt) override;
|
||||
std::expected<void, PacketError> poll() override;
|
||||
std::expected<void, PacketError> send(packet &pkt) override;
|
||||
void DisconnectNet(plr_t plr) override;
|
||||
|
||||
bool SNetLeaveGame(net::leaveinfo_t type) override;
|
||||
@@ -66,18 +66,18 @@ private:
|
||||
bool isGameHost_;
|
||||
|
||||
plr_t get_master();
|
||||
tl::expected<void, PacketError> InitiateHandshake(plr_t player);
|
||||
tl::expected<void, PacketError> SendTo(plr_t player, packet &pkt);
|
||||
std::expected<void, PacketError> InitiateHandshake(plr_t player);
|
||||
std::expected<void, PacketError> SendTo(plr_t player, packet &pkt);
|
||||
void DrainSendQueue(plr_t player);
|
||||
void recv();
|
||||
tl::expected<void, PacketError> handle_join_request(packet &pkt, endpoint_t sender);
|
||||
tl::expected<void, PacketError> recv_decrypted(packet &pkt, endpoint_t sender);
|
||||
tl::expected<void, PacketError> recv_ingame(packet &pkt, endpoint_t sender);
|
||||
std::expected<void, PacketError> handle_join_request(packet &pkt, endpoint_t sender);
|
||||
std::expected<void, PacketError> recv_decrypted(packet &pkt, endpoint_t sender);
|
||||
std::expected<void, PacketError> recv_ingame(packet &pkt, endpoint_t sender);
|
||||
bool is_recognized(endpoint_t sender);
|
||||
|
||||
tl::expected<void, PacketError> wait_network();
|
||||
tl::expected<void, PacketError> wait_firstpeer();
|
||||
tl::expected<void, PacketError> wait_join();
|
||||
std::expected<void, PacketError> wait_network();
|
||||
std::expected<void, PacketError> wait_firstpeer();
|
||||
std::expected<void, PacketError> wait_join();
|
||||
};
|
||||
|
||||
template <class P>
|
||||
@@ -91,18 +91,18 @@ plr_t base_protocol<P>::get_master()
|
||||
}
|
||||
|
||||
template <class P>
|
||||
tl::expected<void, PacketError> base_protocol<P>::wait_network()
|
||||
std::expected<void, PacketError> base_protocol<P>::wait_network()
|
||||
{
|
||||
// wait for ZeroTier for 5 seconds
|
||||
for (auto i = 0; i < 500; ++i) {
|
||||
tl::expected<bool, PacketError> status = proto.network_online();
|
||||
std::expected<bool, PacketError> status = proto.network_online();
|
||||
if (!status.has_value())
|
||||
return tl::make_unexpected(std::move(status).error());
|
||||
return std::unexpected(std::move(status).error());
|
||||
if (*status)
|
||||
return {};
|
||||
SDL_Delay(10);
|
||||
}
|
||||
return tl::make_unexpected("Timeout waiting for ZeroTier network initialization");
|
||||
return std::unexpected("Timeout waiting for ZeroTier network initialization");
|
||||
}
|
||||
|
||||
template <class P>
|
||||
@@ -114,7 +114,7 @@ void base_protocol<P>::DisconnectNet(plr_t plr)
|
||||
}
|
||||
|
||||
template <class P>
|
||||
tl::expected<void, PacketError> base_protocol<P>::wait_firstpeer()
|
||||
std::expected<void, PacketError> base_protocol<P>::wait_firstpeer()
|
||||
{
|
||||
firstpeer = {};
|
||||
// wait for peer for 5 seconds
|
||||
@@ -129,21 +129,21 @@ tl::expected<void, PacketError> base_protocol<P>::wait_firstpeer()
|
||||
SDL_Delay(10);
|
||||
}
|
||||
if (!firstpeer)
|
||||
return tl::make_unexpected("Timeout waiting for response from game host");
|
||||
return std::unexpected("Timeout waiting for response from game host");
|
||||
return {};
|
||||
}
|
||||
|
||||
template <class P>
|
||||
bool base_protocol<P>::send_info_request()
|
||||
{
|
||||
tl::expected<bool, PacketError> status = proto.peers_ready();
|
||||
std::expected<bool, PacketError> status = proto.peers_ready();
|
||||
if (!status.has_value()) {
|
||||
LogError("peers_ready: {}", status.error().what());
|
||||
return false;
|
||||
}
|
||||
if (!*status)
|
||||
return false;
|
||||
tl::expected<std::unique_ptr<packet>, PacketError> pkt
|
||||
std::expected<std::unique_ptr<packet>, PacketError> pkt
|
||||
= pktfty->make_packet<PT_INFO_REQUEST>(PLR_BROADCAST, PLR_MASTER);
|
||||
if (!pkt.has_value()) {
|
||||
LogError("make_packet: {}", pkt.error().what());
|
||||
@@ -154,15 +154,15 @@ bool base_protocol<P>::send_info_request()
|
||||
}
|
||||
|
||||
template <class P>
|
||||
tl::expected<void, PacketError> base_protocol<P>::wait_join()
|
||||
std::expected<void, PacketError> base_protocol<P>::wait_join()
|
||||
{
|
||||
cookie_self = packet_out::GenerateCookie();
|
||||
tl::expected<std::unique_ptr<packet>, PacketError> pkt
|
||||
std::expected<std::unique_ptr<packet>, PacketError> pkt
|
||||
= pktfty->make_packet<PT_JOIN_REQUEST>(PLR_BROADCAST, PLR_MASTER, cookie_self, game_init_info);
|
||||
if (!pkt.has_value()) {
|
||||
return tl::make_unexpected(pkt.error());
|
||||
return std::unexpected(pkt.error());
|
||||
}
|
||||
tl::expected<void, PacketError> result = proto.send(firstpeer, (*pkt)->Data());
|
||||
std::expected<void, PacketError> result = proto.send(firstpeer, (*pkt)->Data());
|
||||
if (!result.has_value()) {
|
||||
return result;
|
||||
}
|
||||
@@ -172,7 +172,7 @@ tl::expected<void, PacketError> base_protocol<P>::wait_join()
|
||||
return {}; // join successful
|
||||
SDL_Delay(10);
|
||||
}
|
||||
return tl::make_unexpected("Timeout waiting to join game");
|
||||
return std::unexpected("Timeout waiting to join game");
|
||||
}
|
||||
|
||||
template <class P>
|
||||
@@ -181,14 +181,14 @@ int base_protocol<P>::create(std::string_view addrstr)
|
||||
gamename = addrstr;
|
||||
isGameHost_ = true;
|
||||
|
||||
tl::expected<void, PacketError> isReady = wait_network();
|
||||
std::expected<void, PacketError> isReady = wait_network();
|
||||
if (!isReady.has_value()) {
|
||||
const std::string_view message = isReady.error().what();
|
||||
SDL_SetError("%.*s", static_cast<int>(message.size()), message.data());
|
||||
return -1;
|
||||
}
|
||||
plr_self = 0;
|
||||
if (tl::expected<void, PacketError> result = Connect(plr_self);
|
||||
if (std::expected<void, PacketError> result = Connect(plr_self);
|
||||
!result.has_value()) {
|
||||
const std::string_view message = result.error().what();
|
||||
SDL_SetError("%.*s", static_cast<int>(message.size()), message.data());
|
||||
@@ -203,19 +203,19 @@ int base_protocol<P>::join(std::string_view addrstr)
|
||||
gamename = addrstr;
|
||||
isGameHost_ = false;
|
||||
|
||||
tl::expected<void, PacketError> isReady = wait_network();
|
||||
std::expected<void, PacketError> isReady = wait_network();
|
||||
if (!isReady.has_value()) {
|
||||
const std::string_view message = isReady.error().what();
|
||||
SDL_SetError("%.*s", static_cast<int>(message.size()), message.data());
|
||||
return -1;
|
||||
}
|
||||
tl::expected<void, PacketError> isPeerReady = wait_firstpeer();
|
||||
std::expected<void, PacketError> isPeerReady = wait_firstpeer();
|
||||
if (!isPeerReady.has_value()) {
|
||||
const std::string_view message = isPeerReady.error().what();
|
||||
SDL_SetError("%.*s", static_cast<int>(message.size()), message.data());
|
||||
return -1;
|
||||
}
|
||||
tl::expected<void, PacketError> isJoined = wait_join();
|
||||
std::expected<void, PacketError> isJoined = wait_join();
|
||||
if (!isJoined.has_value()) {
|
||||
const std::string_view message = isJoined.error().what();
|
||||
SDL_SetError("%.*s", static_cast<int>(message.size()), message.data());
|
||||
@@ -231,14 +231,14 @@ bool base_protocol<P>::IsGameHost()
|
||||
}
|
||||
|
||||
template <class P>
|
||||
tl::expected<void, PacketError> base_protocol<P>::poll()
|
||||
std::expected<void, PacketError> base_protocol<P>::poll()
|
||||
{
|
||||
recv();
|
||||
return {};
|
||||
}
|
||||
|
||||
template <class P>
|
||||
tl::expected<void, PacketError> base_protocol<P>::InitiateHandshake(plr_t player)
|
||||
std::expected<void, PacketError> base_protocol<P>::InitiateHandshake(plr_t player)
|
||||
{
|
||||
Peer &peer = peers[player];
|
||||
|
||||
@@ -253,26 +253,26 @@ tl::expected<void, PacketError> base_protocol<P>::InitiateHandshake(plr_t player
|
||||
}
|
||||
|
||||
template <class P>
|
||||
tl::expected<void, PacketError> base_protocol<P>::send(packet &pkt)
|
||||
std::expected<void, PacketError> base_protocol<P>::send(packet &pkt)
|
||||
{
|
||||
plr_t destination = pkt.Destination();
|
||||
if (destination == PLR_BROADCAST) {
|
||||
for (plr_t player = 0; player < Players.size(); player++) {
|
||||
tl::expected<void, PacketError> result = SendTo(player, pkt);
|
||||
std::expected<void, PacketError> result = SendTo(player, pkt);
|
||||
if (!result.has_value())
|
||||
LogError("Failed to send packet {} to player {}: {}", static_cast<uint8_t>(pkt.Type()), player, result.error().what());
|
||||
}
|
||||
return {};
|
||||
}
|
||||
if (destination >= MAX_PLRS)
|
||||
return tl::make_unexpected("Invalid player ID");
|
||||
return std::unexpected("Invalid player ID");
|
||||
if (destination == plr_self)
|
||||
return {};
|
||||
return SendTo(destination, pkt);
|
||||
}
|
||||
|
||||
template <class P>
|
||||
tl::expected<void, PacketError> base_protocol<P>::SendTo(plr_t player, packet &pkt)
|
||||
std::expected<void, PacketError> base_protocol<P>::SendTo(plr_t player, packet &pkt)
|
||||
{
|
||||
Peer &peer = peers[player];
|
||||
if (!peer.endpoint)
|
||||
@@ -294,7 +294,7 @@ void base_protocol<P>::recv()
|
||||
buffer_t pkt_buf;
|
||||
endpoint_t sender;
|
||||
while (proto.recv(sender, pkt_buf)) { // read until kernel buffer is empty?
|
||||
tl::expected<void, PacketError> result
|
||||
std::expected<void, PacketError> result
|
||||
= pktfty->make_packet(pkt_buf)
|
||||
.and_then([&](std::unique_ptr<packet> &&pkt) {
|
||||
return recv_decrypted(*pkt, sender);
|
||||
@@ -316,7 +316,7 @@ void base_protocol<P>::recv()
|
||||
}
|
||||
|
||||
template <class P>
|
||||
tl::expected<void, PacketError> base_protocol<P>::handle_join_request(packet &inPkt, endpoint_t sender)
|
||||
std::expected<void, PacketError> base_protocol<P>::handle_join_request(packet &inPkt, endpoint_t sender)
|
||||
{
|
||||
plr_t i;
|
||||
for (i = 0; i < Players.size(); ++i) {
|
||||
@@ -324,7 +324,7 @@ tl::expected<void, PacketError> base_protocol<P>::handle_join_request(packet &in
|
||||
if (i != plr_self && !peer.endpoint) {
|
||||
peer.endpoint = sender;
|
||||
peer.sendQueue = std::make_unique<std::deque<packet>>();
|
||||
if (tl::expected<void, PacketError> result = Connect(i);
|
||||
if (std::expected<void, PacketError> result = Connect(i);
|
||||
!result.has_value()) {
|
||||
return result;
|
||||
}
|
||||
@@ -340,7 +340,7 @@ tl::expected<void, PacketError> base_protocol<P>::handle_join_request(packet &in
|
||||
for (plr_t j = 0; j < Players.size(); ++j) {
|
||||
endpoint_t peer = peers[j].endpoint;
|
||||
if ((j != plr_self) && (j != i) && peer) {
|
||||
tl::expected<void, PacketError> result
|
||||
std::expected<void, PacketError> result
|
||||
= pktfty->make_packet<PT_CONNECT>(PLR_MASTER, PLR_BROADCAST, i, senderinfo)
|
||||
.and_then([&](std::unique_ptr<packet> &&pkt) { return proto.send(peer, pkt->Data()); })
|
||||
.and_then([&]() { return pktfty->make_packet<PT_CONNECT>(PLR_MASTER, PLR_BROADCAST, j, peer.serialize()); })
|
||||
@@ -352,14 +352,14 @@ tl::expected<void, PacketError> base_protocol<P>::handle_join_request(packet &in
|
||||
|
||||
// PT_JOIN_ACCEPT must be sent after all PT_CONNECT packets so the new player does
|
||||
// not resume game logic until after having been notified of all existing players
|
||||
tl::expected<cookie_t, PacketError> cookie = inPkt.Cookie();
|
||||
std::expected<cookie_t, PacketError> cookie = inPkt.Cookie();
|
||||
if (!cookie.has_value())
|
||||
return tl::make_unexpected(cookie.error());
|
||||
tl::expected<std::unique_ptr<packet>, PacketError> pkt
|
||||
return std::unexpected(cookie.error());
|
||||
std::expected<std::unique_ptr<packet>, PacketError> pkt
|
||||
= pktfty->make_packet<PT_JOIN_ACCEPT>(plr_self, PLR_BROADCAST, *cookie, i, game_init_info);
|
||||
if (!pkt.has_value())
|
||||
return tl::make_unexpected(pkt.error());
|
||||
tl::expected<void, PacketError> result = proto.send(sender, (*pkt)->Data());
|
||||
return std::unexpected(pkt.error());
|
||||
std::expected<void, PacketError> result = proto.send(sender, (*pkt)->Data());
|
||||
if (!result.has_value())
|
||||
return result;
|
||||
DrainSendQueue(i);
|
||||
@@ -367,13 +367,13 @@ tl::expected<void, PacketError> base_protocol<P>::handle_join_request(packet &in
|
||||
}
|
||||
|
||||
template <class P>
|
||||
tl::expected<void, PacketError> base_protocol<P>::recv_decrypted(packet &pkt, endpoint_t sender)
|
||||
std::expected<void, PacketError> base_protocol<P>::recv_decrypted(packet &pkt, endpoint_t sender)
|
||||
{
|
||||
if (pkt.Source() == PLR_BROADCAST && pkt.Destination() == PLR_MASTER && pkt.Type() == PT_INFO_REPLY) {
|
||||
size_t neededSize = sizeof(GameData) + (PlayerNameLength * MAX_PLRS);
|
||||
const tl::expected<const buffer_t *, PacketError> pktInfo = pkt.Info();
|
||||
const std::expected<const buffer_t *, PacketError> pktInfo = pkt.Info();
|
||||
if (!pktInfo.has_value())
|
||||
return tl::make_unexpected(pktInfo.error());
|
||||
return std::unexpected(pktInfo.error());
|
||||
const buffer_t &infoBuffer = **pktInfo;
|
||||
if (infoBuffer.size() < neededSize)
|
||||
return {};
|
||||
@@ -406,11 +406,11 @@ tl::expected<void, PacketError> base_protocol<P>::recv_decrypted(packet &pkt, en
|
||||
}
|
||||
|
||||
template <class P>
|
||||
tl::expected<void, PacketError> base_protocol<P>::recv_ingame(packet &pkt, endpoint_t sender)
|
||||
std::expected<void, PacketError> base_protocol<P>::recv_ingame(packet &pkt, endpoint_t sender)
|
||||
{
|
||||
if (pkt.Source() == PLR_BROADCAST && pkt.Destination() == PLR_MASTER) {
|
||||
if (pkt.Type() == PT_JOIN_REQUEST) {
|
||||
if (tl::expected<void, PacketError> result = handle_join_request(pkt, sender);
|
||||
if (std::expected<void, PacketError> result = handle_join_request(pkt, sender);
|
||||
!result.has_value()) {
|
||||
return result;
|
||||
}
|
||||
@@ -427,10 +427,10 @@ tl::expected<void, PacketError> base_protocol<P>::recv_ingame(packet &pkt, endpo
|
||||
}
|
||||
}
|
||||
std::memcpy(buf.data() + game_init_info.size() + (PlayerNameLength * MAX_PLRS), &gamename[0], gamename.size());
|
||||
tl::expected<std::unique_ptr<packet>, PacketError> reply
|
||||
std::expected<std::unique_ptr<packet>, PacketError> reply
|
||||
= pktfty->make_packet<PT_INFO_REPLY>(PLR_BROADCAST, PLR_MASTER, buf);
|
||||
if (!reply.has_value()) {
|
||||
return tl::make_unexpected(reply.error());
|
||||
return std::unexpected(reply.error());
|
||||
}
|
||||
proto.send_oob(sender, (*reply)->Data());
|
||||
}
|
||||
@@ -444,19 +444,19 @@ tl::expected<void, PacketError> base_protocol<P>::recv_ingame(packet &pkt, endpo
|
||||
}
|
||||
|
||||
// addrinfo packets
|
||||
tl::expected<plr_t, PacketError> newPlayer = pkt.NewPlayer();
|
||||
std::expected<plr_t, PacketError> newPlayer = pkt.NewPlayer();
|
||||
if (!newPlayer.has_value())
|
||||
return tl::make_unexpected(newPlayer.error());
|
||||
return std::unexpected(newPlayer.error());
|
||||
Peer &peer = peers[*newPlayer];
|
||||
tl::expected<const buffer_t *, PacketError> pktInfo = pkt.Info();
|
||||
std::expected<const buffer_t *, PacketError> pktInfo = pkt.Info();
|
||||
if (!pktInfo.has_value())
|
||||
return tl::make_unexpected(pktInfo.error());
|
||||
if (tl::expected<void, PacketError> result = peer.endpoint.unserialize(**pktInfo);
|
||||
return std::unexpected(pktInfo.error());
|
||||
if (std::expected<void, PacketError> result = peer.endpoint.unserialize(**pktInfo);
|
||||
!result.has_value()) {
|
||||
return result;
|
||||
}
|
||||
peer.sendQueue = std::make_unique<std::deque<packet>>();
|
||||
if (tl::expected<void, PacketError> result = Connect(*newPlayer);
|
||||
if (std::expected<void, PacketError> result = Connect(*newPlayer);
|
||||
!result.has_value()) {
|
||||
return result;
|
||||
}
|
||||
@@ -473,7 +473,7 @@ tl::expected<void, PacketError> base_protocol<P>::recv_ingame(packet &pkt, endpo
|
||||
if (sender == firstpeer && pkt.Type() == PT_JOIN_ACCEPT) {
|
||||
plr_t src = pkt.Source();
|
||||
peers[src].endpoint = sender;
|
||||
if (tl::expected<void, PacketError> result = Connect(src);
|
||||
if (std::expected<void, PacketError> result = Connect(src);
|
||||
!result.has_value()) {
|
||||
return result;
|
||||
}
|
||||
@@ -486,7 +486,7 @@ tl::expected<void, PacketError> base_protocol<P>::recv_ingame(packet &pkt, endpo
|
||||
return {}; // packet not for us, drop
|
||||
|
||||
bool wasBroadcast = plr_self == PLR_BROADCAST;
|
||||
if (tl::expected<void, PacketError> result = RecvLocal(pkt);
|
||||
if (std::expected<void, PacketError> result = RecvLocal(pkt);
|
||||
!result.has_value()) {
|
||||
return result;
|
||||
}
|
||||
@@ -495,7 +495,7 @@ tl::expected<void, PacketError> base_protocol<P>::recv_ingame(packet &pkt, endpo
|
||||
if (wasBroadcast) {
|
||||
// Send a handshake to everyone just after PT_JOIN_ACCEPT
|
||||
for (plr_t player = 0; player < Players.size(); player++) {
|
||||
if (tl::expected<void, PacketError> result = InitiateHandshake(player);
|
||||
if (std::expected<void, PacketError> result = InitiateHandshake(player);
|
||||
!result.has_value()) {
|
||||
return result;
|
||||
}
|
||||
@@ -517,7 +517,7 @@ void base_protocol<P>::DrainSendQueue(plr_t player)
|
||||
std::deque<packet> &sendQueue = *srcPeer.sendQueue;
|
||||
while (!sendQueue.empty()) {
|
||||
packet &pkt = sendQueue.front();
|
||||
tl::expected<void, PacketError> result = proto.send(srcPeer.endpoint, pkt.Data());
|
||||
std::expected<void, PacketError> result = proto.send(srcPeer.endpoint, pkt.Data());
|
||||
if (!result.has_value())
|
||||
LogError("DrainSendQueue failed to send packet: {}", result.error().what());
|
||||
sendQueue.pop_front();
|
||||
|
||||
@@ -25,10 +25,10 @@ framesize_t frame_queue::Size() const
|
||||
return current_size;
|
||||
}
|
||||
|
||||
tl::expected<buffer_t, PacketError> frame_queue::Read(framesize_t s)
|
||||
std::expected<buffer_t, PacketError> frame_queue::Read(framesize_t s)
|
||||
{
|
||||
if (current_size < s)
|
||||
return tl::make_unexpected(FrameQueueError());
|
||||
return std::unexpected(FrameQueueError());
|
||||
buffer_t ret;
|
||||
while (s > 0 && s >= buffer_deque.front().size()) {
|
||||
const auto bufferSize = static_cast<framesize_t>(buffer_deque.front().size());
|
||||
@@ -56,17 +56,17 @@ void frame_queue::Write(buffer_t buf)
|
||||
buffer_deque.push_back(std::move(buf));
|
||||
}
|
||||
|
||||
tl::expected<bool, PacketError> frame_queue::PacketReady()
|
||||
std::expected<bool, PacketError> frame_queue::PacketReady()
|
||||
{
|
||||
if (nextsize == 0) {
|
||||
if (Size() < sizeof(framesize_t))
|
||||
return false;
|
||||
tl::expected<buffer_t, PacketError> szbuf = Read(sizeof(framesize_t));
|
||||
std::expected<buffer_t, PacketError> szbuf = Read(sizeof(framesize_t));
|
||||
if (!szbuf.has_value())
|
||||
return tl::make_unexpected(szbuf.error());
|
||||
return std::unexpected(szbuf.error());
|
||||
nextsize = LoadLE32(szbuf->data());
|
||||
if (nextsize == 0)
|
||||
return tl::make_unexpected(FrameQueueError());
|
||||
return std::unexpected(FrameQueueError());
|
||||
}
|
||||
return Size() >= (nextsize & frame_size_mask);
|
||||
}
|
||||
@@ -77,22 +77,22 @@ uint16_t frame_queue::ReadPacketFlags()
|
||||
return static_cast<uint16_t>(nextsize >> 16);
|
||||
}
|
||||
|
||||
tl::expected<buffer_t, PacketError> frame_queue::ReadPacket()
|
||||
std::expected<buffer_t, PacketError> frame_queue::ReadPacket()
|
||||
{
|
||||
const framesize_t packetSize = nextsize & frame_size_mask;
|
||||
if (nextsize == 0 || Size() < packetSize)
|
||||
return tl::make_unexpected(FrameQueueError());
|
||||
tl::expected<buffer_t, PacketError> ret = Read(packetSize);
|
||||
return std::unexpected(FrameQueueError());
|
||||
std::expected<buffer_t, PacketError> ret = Read(packetSize);
|
||||
nextsize = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
tl::expected<buffer_t, PacketError> frame_queue::MakeFrame(buffer_t packetbuf, uint16_t flags)
|
||||
std::expected<buffer_t, PacketError> frame_queue::MakeFrame(buffer_t packetbuf, uint16_t flags)
|
||||
{
|
||||
buffer_t ret;
|
||||
const auto size = static_cast<framesize_t>(packetbuf.size());
|
||||
if (size > max_frame_size)
|
||||
return tl::make_unexpected("Buffer exceeds maximum frame size");
|
||||
return std::unexpected("Buffer exceeds maximum frame size");
|
||||
static_assert(sizeof(size) == 4, "framesize_t is not 4 bytes");
|
||||
unsigned char sizeBuf[4];
|
||||
WriteLE32(sizeBuf, size | (static_cast<framesize_t>(flags) << 16));
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
#include <cstdint>
|
||||
#include <deque>
|
||||
#include <exception>
|
||||
#include <expected>
|
||||
#include <vector>
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "dvlnet/packet.h"
|
||||
|
||||
namespace devilution {
|
||||
@@ -26,15 +25,15 @@ private:
|
||||
framesize_t nextsize = 0;
|
||||
|
||||
framesize_t Size() const;
|
||||
tl::expected<buffer_t, PacketError> Read(framesize_t s);
|
||||
std::expected<buffer_t, PacketError> Read(framesize_t s);
|
||||
|
||||
public:
|
||||
tl::expected<bool, PacketError> PacketReady();
|
||||
std::expected<bool, PacketError> PacketReady();
|
||||
uint16_t ReadPacketFlags();
|
||||
tl::expected<buffer_t, PacketError> ReadPacket();
|
||||
std::expected<buffer_t, PacketError> ReadPacket();
|
||||
void Write(buffer_t buf);
|
||||
|
||||
static tl::expected<buffer_t, PacketError> MakeFrame(buffer_t packetbuf, uint16_t flags = 0);
|
||||
static std::expected<buffer_t, PacketError> MakeFrame(buffer_t packetbuf, uint16_t flags = 0);
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
|
||||
+17
-18
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
|
||||
#ifdef PACKET_ENCRYPTION
|
||||
#include <sodium.h>
|
||||
@@ -10,8 +11,6 @@
|
||||
#include <random>
|
||||
#endif
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "utils/algorithm/container.hpp"
|
||||
#include "utils/str_cat.hpp"
|
||||
|
||||
@@ -113,11 +112,11 @@ PacketError PacketTypeError(std::initializer_list<packet_type> expectedTypes, st
|
||||
|
||||
namespace {
|
||||
|
||||
tl::expected<void, PacketError> CheckPacketTypeOneOf(std::initializer_list<packet_type> expectedTypes, std::uint8_t actualType)
|
||||
std::expected<void, PacketError> CheckPacketTypeOneOf(std::initializer_list<packet_type> expectedTypes, std::uint8_t actualType)
|
||||
{
|
||||
if (c_none_of(expectedTypes,
|
||||
[actualType](uint8_t type) { return type == actualType; })) {
|
||||
return tl::make_unexpected(PacketTypeError(expectedTypes, actualType));
|
||||
return std::unexpected(PacketTypeError(expectedTypes, actualType));
|
||||
}
|
||||
return {};
|
||||
}
|
||||
@@ -150,60 +149,60 @@ plr_t packet::Destination() const
|
||||
return m_dest;
|
||||
}
|
||||
|
||||
tl::expected<const buffer_t *, PacketError> packet::Message()
|
||||
std::expected<const buffer_t *, PacketError> packet::Message()
|
||||
{
|
||||
assert(have_decrypted);
|
||||
return CheckPacketTypeOneOf({ PT_MESSAGE }, m_type)
|
||||
.transform([this]() { return &m_message; });
|
||||
}
|
||||
|
||||
tl::expected<turn_t, PacketError> packet::Turn()
|
||||
std::expected<turn_t, PacketError> packet::Turn()
|
||||
{
|
||||
assert(have_decrypted);
|
||||
return CheckPacketTypeOneOf({ PT_TURN }, m_type)
|
||||
.transform([this]() { return m_turn; });
|
||||
}
|
||||
|
||||
tl::expected<cookie_t, PacketError> packet::Cookie()
|
||||
std::expected<cookie_t, PacketError> packet::Cookie()
|
||||
{
|
||||
assert(have_decrypted);
|
||||
return CheckPacketTypeOneOf({ PT_JOIN_REQUEST, PT_JOIN_ACCEPT }, m_type)
|
||||
.transform([this]() { return m_cookie; });
|
||||
}
|
||||
|
||||
tl::expected<plr_t, PacketError> packet::NewPlayer()
|
||||
std::expected<plr_t, PacketError> packet::NewPlayer()
|
||||
{
|
||||
assert(have_decrypted);
|
||||
return CheckPacketTypeOneOf({ PT_JOIN_ACCEPT, PT_CONNECT, PT_DISCONNECT }, m_type)
|
||||
.transform([this]() { return m_newplr; });
|
||||
}
|
||||
|
||||
tl::expected<timestamp_t, PacketError> packet::Time()
|
||||
std::expected<timestamp_t, PacketError> packet::Time()
|
||||
{
|
||||
assert(have_decrypted);
|
||||
return CheckPacketTypeOneOf({ PT_ECHO_REQUEST, PT_ECHO_REPLY }, m_type)
|
||||
.transform([this]() { return m_time; });
|
||||
}
|
||||
|
||||
tl::expected<const buffer_t *, PacketError> packet::Info()
|
||||
std::expected<const buffer_t *, PacketError> packet::Info()
|
||||
{
|
||||
assert(have_decrypted);
|
||||
return CheckPacketTypeOneOf({ PT_JOIN_REQUEST, PT_JOIN_ACCEPT, PT_CONNECT, PT_INFO_REPLY }, m_type)
|
||||
.transform([this]() { return &m_info; });
|
||||
}
|
||||
|
||||
tl::expected<leaveinfo_t, PacketError> packet::LeaveInfo()
|
||||
std::expected<leaveinfo_t, PacketError> packet::LeaveInfo()
|
||||
{
|
||||
assert(have_decrypted);
|
||||
return CheckPacketTypeOneOf({ PT_DISCONNECT }, m_type)
|
||||
.transform([this]() { return m_leaveinfo; });
|
||||
}
|
||||
|
||||
tl::expected<void, PacketError> packet_in::Create(buffer_t buf)
|
||||
std::expected<void, PacketError> packet_in::Create(buffer_t buf)
|
||||
{
|
||||
assert(!have_encrypted && !have_decrypted);
|
||||
if (buf.size() < sizeof(packet_type) + 2 * sizeof(plr_t))
|
||||
return tl::make_unexpected(PacketError());
|
||||
return std::unexpected(PacketError());
|
||||
|
||||
decrypted_buffer = std::move(buf);
|
||||
have_decrypted = true;
|
||||
@@ -217,7 +216,7 @@ tl::expected<void, PacketError> packet_in::Create(buffer_t buf)
|
||||
}
|
||||
|
||||
#ifdef PACKET_ENCRYPTION
|
||||
tl::expected<void, PacketError> packet_in::Decrypt(buffer_t buf)
|
||||
std::expected<void, PacketError> packet_in::Decrypt(buffer_t buf)
|
||||
{
|
||||
assert(!have_encrypted && !have_decrypted);
|
||||
encrypted_buffer = std::move(buf);
|
||||
@@ -226,7 +225,7 @@ tl::expected<void, PacketError> packet_in::Decrypt(buffer_t buf)
|
||||
if (encrypted_buffer.size() < crypto_secretbox_NONCEBYTES
|
||||
+ crypto_secretbox_MACBYTES
|
||||
+ sizeof(packet_type) + 2 * sizeof(plr_t))
|
||||
return tl::make_unexpected(PacketError());
|
||||
return std::unexpected(PacketError());
|
||||
auto pktlen = (encrypted_buffer.size()
|
||||
- crypto_secretbox_NONCEBYTES
|
||||
- crypto_secretbox_MACBYTES);
|
||||
@@ -240,7 +239,7 @@ tl::expected<void, PacketError> packet_in::Decrypt(buffer_t buf)
|
||||
if (status != 0) {
|
||||
auto code = PacketError::ErrorCode::DecryptionFailed;
|
||||
std::string_view message = "Failed to decrypt packet data";
|
||||
return tl::make_unexpected(PacketError(code, message));
|
||||
return std::unexpected(PacketError(code, message));
|
||||
}
|
||||
|
||||
have_decrypted = true;
|
||||
@@ -249,7 +248,7 @@ tl::expected<void, PacketError> packet_in::Decrypt(buffer_t buf)
|
||||
#endif
|
||||
|
||||
#ifdef PACKET_ENCRYPTION
|
||||
tl::expected<void, PacketError> packet_out::Encrypt()
|
||||
std::expected<void, PacketError> packet_out::Encrypt()
|
||||
{
|
||||
assert(have_decrypted);
|
||||
|
||||
@@ -271,7 +270,7 @@ tl::expected<void, PacketError> packet_out::Encrypt()
|
||||
if (status != 0) {
|
||||
auto code = PacketError::ErrorCode::EncryptionFailed;
|
||||
std::string_view message = "Failed to encrypt packet data";
|
||||
return tl::make_unexpected(PacketError(code, message));
|
||||
return std::unexpected(PacketError(code, message));
|
||||
}
|
||||
|
||||
have_encrypted = true;
|
||||
|
||||
+37
-38
@@ -3,12 +3,11 @@
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <expected>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#ifdef PACKET_ENCRYPTION
|
||||
#include <sodium.h>
|
||||
#endif
|
||||
@@ -175,30 +174,30 @@ public:
|
||||
packet_type Type();
|
||||
plr_t Source() const;
|
||||
plr_t Destination() const;
|
||||
tl::expected<const buffer_t *, PacketError> Message();
|
||||
tl::expected<turn_t, PacketError> Turn();
|
||||
tl::expected<cookie_t, PacketError> Cookie();
|
||||
tl::expected<plr_t, PacketError> NewPlayer();
|
||||
tl::expected<timestamp_t, PacketError> Time();
|
||||
tl::expected<const buffer_t *, PacketError> Info();
|
||||
tl::expected<leaveinfo_t, PacketError> LeaveInfo();
|
||||
std::expected<const buffer_t *, PacketError> Message();
|
||||
std::expected<turn_t, PacketError> Turn();
|
||||
std::expected<cookie_t, PacketError> Cookie();
|
||||
std::expected<plr_t, PacketError> NewPlayer();
|
||||
std::expected<timestamp_t, PacketError> Time();
|
||||
std::expected<const buffer_t *, PacketError> Info();
|
||||
std::expected<leaveinfo_t, PacketError> LeaveInfo();
|
||||
};
|
||||
|
||||
template <class P>
|
||||
class packet_proc : public packet {
|
||||
public:
|
||||
using packet::packet;
|
||||
tl::expected<void, PacketError> process_data();
|
||||
std::expected<void, PacketError> process_data();
|
||||
};
|
||||
|
||||
class packet_in : public packet_proc<packet_in> {
|
||||
public:
|
||||
using packet_proc<packet_in>::packet_proc;
|
||||
tl::expected<void, PacketError> Create(buffer_t buf);
|
||||
tl::expected<void, PacketError> process_element(buffer_t &x);
|
||||
std::expected<void, PacketError> Create(buffer_t buf);
|
||||
std::expected<void, PacketError> process_element(buffer_t &x);
|
||||
template <class T>
|
||||
tl::expected<void, PacketError> process_element(T &x);
|
||||
tl::expected<void, PacketError> Decrypt(buffer_t buf);
|
||||
std::expected<void, PacketError> process_element(T &x);
|
||||
std::expected<void, PacketError> Decrypt(buffer_t buf);
|
||||
};
|
||||
|
||||
class packet_out : public packet_proc<packet_out> {
|
||||
@@ -208,19 +207,19 @@ public:
|
||||
template <packet_type t, typename... Args>
|
||||
void create(Args... args);
|
||||
|
||||
tl::expected<void, PacketError> process_element(buffer_t &x);
|
||||
std::expected<void, PacketError> process_element(buffer_t &x);
|
||||
template <class T>
|
||||
tl::expected<void, PacketError> process_element(const T &x);
|
||||
std::expected<void, PacketError> process_element(const T &x);
|
||||
static cookie_t GenerateCookie();
|
||||
tl::expected<void, PacketError> Encrypt();
|
||||
std::expected<void, PacketError> Encrypt();
|
||||
};
|
||||
|
||||
template <class P>
|
||||
tl::expected<void, PacketError> packet_proc<P>::process_data()
|
||||
std::expected<void, PacketError> packet_proc<P>::process_data()
|
||||
{
|
||||
P &self = static_cast<P &>(*this);
|
||||
{
|
||||
tl::expected<void, PacketError> result
|
||||
std::expected<void, PacketError> result
|
||||
= self.process_element(m_type)
|
||||
.and_then([&]() {
|
||||
return self.process_element(m_src);
|
||||
@@ -258,10 +257,10 @@ tl::expected<void, PacketError> packet_proc<P>::process_data()
|
||||
case PT_ECHO_REPLY:
|
||||
return self.process_element(m_time);
|
||||
}
|
||||
return tl::make_unexpected(PacketTypeError(m_type));
|
||||
return std::unexpected(PacketTypeError(m_type));
|
||||
}
|
||||
|
||||
inline tl::expected<void, PacketError> packet_in::process_element(buffer_t &x)
|
||||
inline std::expected<void, PacketError> packet_in::process_element(buffer_t &x)
|
||||
{
|
||||
x.insert(x.begin(), decrypted_buffer.begin(), decrypted_buffer.end());
|
||||
decrypted_buffer.resize(0);
|
||||
@@ -269,12 +268,12 @@ inline tl::expected<void, PacketError> packet_in::process_element(buffer_t &x)
|
||||
}
|
||||
|
||||
template <class T>
|
||||
tl::expected<void, PacketError> packet_in::process_element(T &x)
|
||||
std::expected<void, PacketError> packet_in::process_element(T &x)
|
||||
{
|
||||
static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "Unsupported T");
|
||||
static_assert(sizeof(T) == 4 || sizeof(T) == 2 || sizeof(T) == 1, "Unsupported T");
|
||||
if (decrypted_buffer.size() < sizeof(T)) {
|
||||
return tl::make_unexpected(PacketError());
|
||||
return std::unexpected(PacketError());
|
||||
}
|
||||
if (sizeof(T) == 4) {
|
||||
x = static_cast<T>(LoadLE32(decrypted_buffer.data()));
|
||||
@@ -427,14 +426,14 @@ inline void packet_out::create<PT_ECHO_REPLY>(plr_t s, plr_t d, timestamp_t t)
|
||||
m_time = t;
|
||||
}
|
||||
|
||||
inline tl::expected<void, PacketError> packet_out::process_element(buffer_t &x)
|
||||
inline std::expected<void, PacketError> packet_out::process_element(buffer_t &x)
|
||||
{
|
||||
decrypted_buffer.insert(decrypted_buffer.end(), x.begin(), x.end());
|
||||
return {};
|
||||
}
|
||||
|
||||
template <class T>
|
||||
tl::expected<void, PacketError> packet_out::process_element(const T &x)
|
||||
std::expected<void, PacketError> packet_out::process_element(const T &x)
|
||||
{
|
||||
static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "Unsupported T");
|
||||
static_assert(sizeof(T) == 4 || sizeof(T) == 2 || sizeof(T) == 1, "Unsupported T");
|
||||
@@ -469,43 +468,43 @@ public:
|
||||
|
||||
packet_factory();
|
||||
packet_factory(std::string pw);
|
||||
tl::expected<std::unique_ptr<packet>, PacketError> make_packet(buffer_t buf);
|
||||
std::expected<std::unique_ptr<packet>, PacketError> make_packet(buffer_t buf);
|
||||
template <packet_type t, typename... Args>
|
||||
tl::expected<std::unique_ptr<packet>, PacketError> make_packet(Args... args);
|
||||
std::expected<std::unique_ptr<packet>, PacketError> make_packet(Args... args);
|
||||
};
|
||||
|
||||
inline tl::expected<std::unique_ptr<packet>, PacketError> packet_factory::make_packet(buffer_t buf)
|
||||
inline std::expected<std::unique_ptr<packet>, PacketError> packet_factory::make_packet(buffer_t buf)
|
||||
{
|
||||
auto ret = std::make_unique<packet_in>(key);
|
||||
#ifndef PACKET_ENCRYPTION
|
||||
tl::expected<void, PacketError> isCreated = ret->Create(std::move(buf));
|
||||
std::expected<void, PacketError> isCreated = ret->Create(std::move(buf));
|
||||
#else
|
||||
tl::expected<void, PacketError> isCreated = !secure
|
||||
std::expected<void, PacketError> isCreated = !secure
|
||||
? ret->Create(std::move(buf))
|
||||
: ret->Decrypt(std::move(buf));
|
||||
#endif
|
||||
if (!isCreated.has_value()) {
|
||||
return tl::make_unexpected(isCreated.error());
|
||||
return std::unexpected(isCreated.error());
|
||||
}
|
||||
if (const tl::expected<void, PacketError> result = ret->process_data(); !result.has_value()) {
|
||||
return tl::make_unexpected(result.error());
|
||||
if (const std::expected<void, PacketError> result = ret->process_data(); !result.has_value()) {
|
||||
return std::unexpected(result.error());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <packet_type t, typename... Args>
|
||||
tl::expected<std::unique_ptr<packet>, PacketError> packet_factory::make_packet(Args... args)
|
||||
std::expected<std::unique_ptr<packet>, PacketError> packet_factory::make_packet(Args... args)
|
||||
{
|
||||
auto ret = std::make_unique<packet_out>(key);
|
||||
ret->create<t>(args...);
|
||||
if (const tl::expected<void, PacketError> result = ret->process_data(); !result.has_value()) {
|
||||
return tl::make_unexpected(result.error());
|
||||
if (const std::expected<void, PacketError> result = ret->process_data(); !result.has_value()) {
|
||||
return std::unexpected(result.error());
|
||||
}
|
||||
#ifdef PACKET_ENCRYPTION
|
||||
if (secure) {
|
||||
tl::expected<void, PacketError> isEncrypted = ret->Encrypt();
|
||||
std::expected<void, PacketError> isEncrypted = ret->Encrypt();
|
||||
if (!isEncrypted.has_value()) {
|
||||
return tl::make_unexpected(isEncrypted.error());
|
||||
return std::unexpected(isEncrypted.error());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -92,7 +92,7 @@ void protocol_zt::set_reuseaddr(int fd)
|
||||
lwip_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&yes, sizeof(yes));
|
||||
}
|
||||
|
||||
tl::expected<bool, PacketError> protocol_zt::network_online()
|
||||
std::expected<bool, PacketError> protocol_zt::network_online()
|
||||
{
|
||||
if (!zerotier_network_ready())
|
||||
return false;
|
||||
@@ -110,7 +110,7 @@ tl::expected<bool, PacketError> protocol_zt::network_online()
|
||||
if (ret < 0) {
|
||||
std::string_view format = "Error binding to ZeroTier UDP socket: {}";
|
||||
PacketError error = ProtocolError(format, strerror(errno));
|
||||
return tl::make_unexpected(std::move(error));
|
||||
return std::unexpected(std::move(error));
|
||||
}
|
||||
set_nonblock(fd_udp);
|
||||
}
|
||||
@@ -121,13 +121,13 @@ tl::expected<bool, PacketError> protocol_zt::network_online()
|
||||
if (r1 < 0) {
|
||||
std::string_view format = "Error binding to ZeroTier TCP socket: {}";
|
||||
PacketError error = ProtocolError(format, strerror(errno));
|
||||
return tl::make_unexpected(std::move(error));
|
||||
return std::unexpected(std::move(error));
|
||||
}
|
||||
auto r2 = lwip_listen(fd_tcp, 10);
|
||||
if (r2 < 0) {
|
||||
std::string_view format = "Error listening on ZeroTier TCP socket: {}";
|
||||
PacketError error = ProtocolError(format, strerror(errno));
|
||||
return tl::make_unexpected(std::move(error));
|
||||
return std::unexpected(std::move(error));
|
||||
}
|
||||
set_nonblock(fd_tcp);
|
||||
set_nodelay(fd_tcp);
|
||||
@@ -135,17 +135,17 @@ tl::expected<bool, PacketError> protocol_zt::network_online()
|
||||
return true;
|
||||
}
|
||||
|
||||
tl::expected<bool, PacketError> protocol_zt::peers_ready()
|
||||
std::expected<bool, PacketError> protocol_zt::peers_ready()
|
||||
{
|
||||
return network_online()
|
||||
.map([&](bool isOnline) { return isOnline && zerotier_peers_ready(); });
|
||||
.transform([&](bool isOnline) { return isOnline && zerotier_peers_ready(); });
|
||||
}
|
||||
|
||||
tl::expected<void, PacketError> protocol_zt::send(const endpoint &peer, const buffer_t &data)
|
||||
std::expected<void, PacketError> protocol_zt::send(const endpoint &peer, const buffer_t &data)
|
||||
{
|
||||
tl::expected<buffer_t, PacketError> frame = frame_queue::MakeFrame(data);
|
||||
std::expected<buffer_t, PacketError> frame = frame_queue::MakeFrame(data);
|
||||
if (!frame.has_value())
|
||||
return tl::make_unexpected(frame.error());
|
||||
return std::unexpected(frame.error());
|
||||
peer_list[peer].send_queue.push_back(*frame);
|
||||
return {};
|
||||
}
|
||||
@@ -168,7 +168,7 @@ bool protocol_zt::send_oob_mc(const buffer_t &data) const
|
||||
return send_oob(mc, data);
|
||||
}
|
||||
|
||||
tl::expected<bool, PacketError> protocol_zt::send_queued_peer(const endpoint &peer)
|
||||
std::expected<bool, PacketError> protocol_zt::send_queued_peer(const endpoint &peer)
|
||||
{
|
||||
peer_state &state = peer_list[peer];
|
||||
if (state.fd == -1) {
|
||||
@@ -200,7 +200,7 @@ tl::expected<bool, PacketError> protocol_zt::send_queued_peer(const endpoint &pe
|
||||
} else {
|
||||
std::string_view format = "Impossible number of bytes sent: {} available, {} sent";
|
||||
PacketError error = ProtocolError(format, len, decltype(len)(r));
|
||||
return tl::make_unexpected(std::move(error));
|
||||
return std::unexpected(std::move(error));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -223,7 +223,7 @@ bool protocol_zt::recv_peer(const endpoint &peer)
|
||||
bool protocol_zt::send_queued_all()
|
||||
{
|
||||
for (const auto &[endpoint, _] : peer_list) {
|
||||
tl::expected<bool, PacketError> result = send_queued_peer(endpoint);
|
||||
std::expected<bool, PacketError> result = send_queued_peer(endpoint);
|
||||
if (!result.has_value()) {
|
||||
LogError("send_queued_peer: {}", result.error().what());
|
||||
continue;
|
||||
@@ -302,14 +302,14 @@ bool protocol_zt::recv(endpoint &peer, buffer_t &data)
|
||||
}
|
||||
|
||||
for (auto &p : peer_list) {
|
||||
tl::expected<bool, PacketError> ready = p.second.recv_queue.PacketReady();
|
||||
std::expected<bool, PacketError> ready = p.second.recv_queue.PacketReady();
|
||||
if (!ready.has_value()) {
|
||||
LogError("PacketReady: {}", ready.error().what());
|
||||
continue;
|
||||
}
|
||||
if (!*ready)
|
||||
continue;
|
||||
tl::expected<buffer_t, PacketError> packet = p.second.recv_queue.ReadPacket();
|
||||
std::expected<buffer_t, PacketError> packet = p.second.recv_queue.ReadPacket();
|
||||
if (!packet.has_value()) {
|
||||
LogError("Failed reading packet data from peer: {}", packet.error().what());
|
||||
continue;
|
||||
|
||||
@@ -57,12 +57,12 @@ public:
|
||||
return buffer_t(addr.begin(), addr.end());
|
||||
}
|
||||
|
||||
tl::expected<void, PacketError> unserialize(const buffer_t &buf)
|
||||
std::expected<void, PacketError> unserialize(const buffer_t &buf)
|
||||
{
|
||||
if (buf.size() != 16) {
|
||||
std::string_view format = "Endpoint deserialization expected 16 bytes, got {}";
|
||||
PacketError error = ProtocolError(format, buf.size());
|
||||
return tl::make_unexpected(std::move(error));
|
||||
return std::unexpected(std::move(error));
|
||||
}
|
||||
std::copy(buf.begin(), buf.end(), addr.begin());
|
||||
return {};
|
||||
@@ -83,13 +83,13 @@ public:
|
||||
protocol_zt();
|
||||
~protocol_zt();
|
||||
void disconnect(const endpoint &peer);
|
||||
tl::expected<void, PacketError> send(const endpoint &peer, const buffer_t &data);
|
||||
std::expected<void, PacketError> send(const endpoint &peer, const buffer_t &data);
|
||||
bool send_oob(const endpoint &peer, const buffer_t &data) const;
|
||||
bool send_oob_mc(const buffer_t &data) const;
|
||||
bool recv(endpoint &peer, buffer_t &data);
|
||||
bool get_disconnected(endpoint &peer);
|
||||
tl::expected<bool, PacketError> network_online();
|
||||
tl::expected<bool, PacketError> peers_ready();
|
||||
std::expected<bool, PacketError> network_online();
|
||||
std::expected<bool, PacketError> peers_ready();
|
||||
bool is_peer_connected(endpoint &peer);
|
||||
std::optional<bool> is_peer_relayed(const endpoint &peer) const;
|
||||
std::optional<int> get_latency_to(const endpoint &peer) const;
|
||||
@@ -119,7 +119,7 @@ private:
|
||||
static void set_nodelay(int fd);
|
||||
static void set_reuseaddr(int fd);
|
||||
|
||||
tl::expected<bool, PacketError> send_queued_peer(const endpoint &peer);
|
||||
std::expected<bool, PacketError> send_queued_peer(const endpoint &peer);
|
||||
bool recv_peer(const endpoint &peer);
|
||||
bool send_queued_all();
|
||||
bool recv_from_peers();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "dvlnet/tcp_client.h"
|
||||
|
||||
#include <exception>
|
||||
#include <expected>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
@@ -14,7 +15,6 @@
|
||||
#endif
|
||||
|
||||
#include <asio/connect.hpp>
|
||||
#include <expected.hpp>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "options.h"
|
||||
@@ -89,7 +89,7 @@ int tcp_client::join(std::string_view addrstr)
|
||||
StartReceive();
|
||||
{
|
||||
cookie_self = packet_out::GenerateCookie();
|
||||
tl::expected<std::unique_ptr<packet>, PacketError> pkt
|
||||
std::expected<std::unique_ptr<packet>, PacketError> pkt
|
||||
= pktfty->make_packet<PT_JOIN_REQUEST>(
|
||||
PLR_BROADCAST, PLR_MASTER, cookie_self, game_init_info);
|
||||
if (!pkt.has_value()) {
|
||||
@@ -97,14 +97,14 @@ int tcp_client::join(std::string_view addrstr)
|
||||
SDL_SetError("make_packet: %.*s", static_cast<int>(message.size()), message.data());
|
||||
return -1;
|
||||
}
|
||||
tl::expected<void, PacketError> sendResult = send(**pkt);
|
||||
std::expected<void, PacketError> sendResult = send(**pkt);
|
||||
if (!sendResult.has_value()) {
|
||||
const std::string_view message = sendResult.error().what();
|
||||
SDL_SetError("send: %.*s", static_cast<int>(message.size()), message.data());
|
||||
return -1;
|
||||
}
|
||||
for (auto i = 0; i < NoSleep; ++i) {
|
||||
tl::expected<void, PacketError> pollResult = poll();
|
||||
std::expected<void, PacketError> pollResult = poll();
|
||||
if (!pollResult.has_value()) {
|
||||
const std::string_view message = pollResult.error().what();
|
||||
SDL_SetError("%.*s", static_cast<int>(message.size()), message.data());
|
||||
@@ -129,17 +129,17 @@ bool tcp_client::IsGameHost()
|
||||
return local_server != nullptr;
|
||||
}
|
||||
|
||||
tl::expected<void, PacketError> tcp_client::poll()
|
||||
std::expected<void, PacketError> tcp_client::poll()
|
||||
{
|
||||
while (ioc.poll_one() > 0) {
|
||||
if (IsGameHost()) {
|
||||
tl::expected<void, PacketError> serverResult = local_server->CheckIoHandlerError();
|
||||
std::expected<void, PacketError> serverResult = local_server->CheckIoHandlerError();
|
||||
if (!serverResult.has_value())
|
||||
return serverResult;
|
||||
}
|
||||
if (ioHandlerResult == std::nullopt)
|
||||
continue;
|
||||
tl::expected<void, PacketError> packetError = tl::make_unexpected(*ioHandlerResult);
|
||||
std::expected<void, PacketError> packetError = std::unexpected(*ioHandlerResult);
|
||||
ioHandlerResult = std::nullopt;
|
||||
return packetError;
|
||||
}
|
||||
@@ -162,7 +162,7 @@ void tcp_client::HandleReceive(const asio::error_code &error, size_t bytesRead)
|
||||
recv_queue.Write(std::move(recv_buffer));
|
||||
recv_buffer.resize(frame_queue::max_frame_size);
|
||||
while (true) {
|
||||
tl::expected<bool, PacketError> ready = recv_queue.PacketReady();
|
||||
std::expected<bool, PacketError> ready = recv_queue.PacketReady();
|
||||
if (!ready.has_value()) {
|
||||
RaiseIoHandlerError(ready.error());
|
||||
return;
|
||||
@@ -173,7 +173,7 @@ void tcp_client::HandleReceive(const asio::error_code &error, size_t bytesRead)
|
||||
HandleTcpErrorCode();
|
||||
return;
|
||||
}
|
||||
tl::expected<void, PacketError> result
|
||||
std::expected<void, PacketError> result
|
||||
= recv_queue.ReadPacket()
|
||||
.and_then([this](buffer_t &&pktData) { return pktfty->make_packet(pktData); })
|
||||
.and_then([this](std::unique_ptr<packet> &&pkt) { return RecvLocal(*pkt); });
|
||||
@@ -200,7 +200,7 @@ void tcp_client::HandleSend(const asio::error_code &error, size_t /*bytesSent*/)
|
||||
|
||||
void tcp_client::HandleTcpErrorCode()
|
||||
{
|
||||
tl::expected<buffer_t, PacketError> packet = recv_queue.ReadPacket();
|
||||
std::expected<buffer_t, PacketError> packet = recv_queue.ReadPacket();
|
||||
if (!packet.has_value()) {
|
||||
RaiseIoHandlerError(packet.error());
|
||||
return;
|
||||
@@ -219,11 +219,11 @@ void tcp_client::HandleTcpErrorCode()
|
||||
RaiseIoHandlerError(fmt::format("Unknown error code received from server: {:#04x}", pktData[0]));
|
||||
}
|
||||
|
||||
tl::expected<void, PacketError> tcp_client::send(packet &pkt)
|
||||
std::expected<void, PacketError> tcp_client::send(packet &pkt)
|
||||
{
|
||||
tl::expected<buffer_t, PacketError> frame = frame_queue::MakeFrame(pkt.Data());
|
||||
std::expected<buffer_t, PacketError> frame = frame_queue::MakeFrame(pkt.Data());
|
||||
if (!frame.has_value())
|
||||
return tl::make_unexpected(frame.error());
|
||||
return std::unexpected(frame.error());
|
||||
std::unique_ptr<buffer_t> framePtr = std::make_unique<buffer_t>(*frame);
|
||||
const asio::mutable_buffer buf = asio::buffer(*framePtr);
|
||||
asio::async_write(sock, buf, [this, frame = std::move(framePtr)](const asio::error_code &error, size_t bytesSent) {
|
||||
|
||||
@@ -30,8 +30,8 @@ public:
|
||||
int create(std::string_view addrstr) override;
|
||||
int join(std::string_view addrstr) override;
|
||||
|
||||
tl::expected<void, PacketError> poll() override;
|
||||
tl::expected<void, PacketError> send(packet &pkt) override;
|
||||
std::expected<void, PacketError> poll() override;
|
||||
std::expected<void, PacketError> send(packet &pkt) override;
|
||||
void DisconnectNet(plr_t plr) override;
|
||||
|
||||
bool SNetLeaveGame(net::leaveinfo_t type) override;
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
#include "dvlnet/tcp_server.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <expected>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "dvlnet/base.h"
|
||||
#include "player.h"
|
||||
#include "utils/log.hpp"
|
||||
@@ -78,7 +77,7 @@ void tcp_server::HandleReceive(const scc &con, const asio::error_code &ec,
|
||||
con->recv_queue.Write(std::move(con->recv_buffer));
|
||||
con->recv_buffer.resize(frame_queue::max_frame_size);
|
||||
while (true) {
|
||||
tl::expected<bool, PacketError> ready = con->recv_queue.PacketReady();
|
||||
std::expected<bool, PacketError> ready = con->recv_queue.PacketReady();
|
||||
if (!ready.has_value()) {
|
||||
Log("PacketReady: {}", ready.error().what());
|
||||
DropConnection(con);
|
||||
@@ -86,13 +85,13 @@ void tcp_server::HandleReceive(const scc &con, const asio::error_code &ec,
|
||||
}
|
||||
if (!*ready)
|
||||
break;
|
||||
tl::expected<buffer_t, PacketError> pktData = con->recv_queue.ReadPacket();
|
||||
std::expected<buffer_t, PacketError> pktData = con->recv_queue.ReadPacket();
|
||||
if (!pktData.has_value()) {
|
||||
Log("ReadPacket: {}", pktData.error().what());
|
||||
DropConnection(con);
|
||||
return;
|
||||
}
|
||||
tl::expected<std::unique_ptr<packet>, PacketError> pkt = pktfty.make_packet(*pktData);
|
||||
std::expected<std::unique_ptr<packet>, PacketError> pkt = pktfty.make_packet(*pktData);
|
||||
if (!pkt.has_value()) {
|
||||
Log("make_packet: {}", pkt.error().what());
|
||||
if (pkt.error().code() == PacketError::ErrorCode::DecryptionFailed)
|
||||
@@ -101,7 +100,7 @@ void tcp_server::HandleReceive(const scc &con, const asio::error_code &ec,
|
||||
return;
|
||||
}
|
||||
if (con->plr == PLR_BROADCAST) {
|
||||
tl::expected<void, PacketError> result = HandleReceiveNewPlayer(con, **pkt);
|
||||
std::expected<void, PacketError> result = HandleReceiveNewPlayer(con, **pkt);
|
||||
if (!result.has_value()) {
|
||||
Log("HandleReceiveNewPlayer: {}", result.error().what());
|
||||
DropConnection(con);
|
||||
@@ -109,7 +108,7 @@ void tcp_server::HandleReceive(const scc &con, const asio::error_code &ec,
|
||||
}
|
||||
} else {
|
||||
con->timeout = timeout_active;
|
||||
tl::expected<void, PacketError> result = HandleReceivePacket(**pkt);
|
||||
std::expected<void, PacketError> result = HandleReceivePacket(**pkt);
|
||||
if (!result.has_value()) {
|
||||
Log("Network error: {}", result.error().what());
|
||||
DropConnection(con);
|
||||
@@ -120,22 +119,22 @@ void tcp_server::HandleReceive(const scc &con, const asio::error_code &ec,
|
||||
StartReceive(con);
|
||||
}
|
||||
|
||||
tl::expected<void, PacketError> tcp_server::HandleReceiveNewPlayer(const scc &con, packet &inPkt)
|
||||
std::expected<void, PacketError> tcp_server::HandleReceiveNewPlayer(const scc &con, packet &inPkt)
|
||||
{
|
||||
auto newplr = NextFree();
|
||||
if (newplr == PLR_BROADCAST)
|
||||
return tl::make_unexpected(ServerError());
|
||||
return std::unexpected(ServerError());
|
||||
|
||||
if (Empty()) {
|
||||
tl::expected<const buffer_t *, PacketError> pktInfo = inPkt.Info();
|
||||
std::expected<const buffer_t *, PacketError> pktInfo = inPkt.Info();
|
||||
if (!pktInfo.has_value())
|
||||
return tl::make_unexpected(pktInfo.error());
|
||||
return std::unexpected(pktInfo.error());
|
||||
game_init_info = **pktInfo;
|
||||
}
|
||||
|
||||
for (plr_t player = 0; player < Players.size(); player++) {
|
||||
if (connections[player]) {
|
||||
tl::expected<void, PacketError> result
|
||||
std::expected<void, PacketError> result
|
||||
= pktfty.make_packet<PT_CONNECT>(PLR_MASTER, PLR_BROADCAST, newplr)
|
||||
.and_then([&](std::unique_ptr<packet> &&pkt) { return StartSend(connections[player], *pkt); })
|
||||
.and_then([&]() { return pktfty.make_packet<PT_CONNECT>(PLR_MASTER, PLR_BROADCAST, player); })
|
||||
@@ -145,7 +144,7 @@ tl::expected<void, PacketError> tcp_server::HandleReceiveNewPlayer(const scc &co
|
||||
}
|
||||
}
|
||||
|
||||
tl::expected<void, PacketError> result
|
||||
std::expected<void, PacketError> result
|
||||
= inPkt.Cookie()
|
||||
.and_then([&](cookie_t &&cookie) { return pktfty.make_packet<PT_JOIN_ACCEPT>(PLR_MASTER, PLR_BROADCAST, cookie, newplr, game_init_info); })
|
||||
.and_then([&](std::unique_ptr<packet> &&pkt) { return StartSend(con, *pkt); });
|
||||
@@ -157,47 +156,47 @@ tl::expected<void, PacketError> tcp_server::HandleReceiveNewPlayer(const scc &co
|
||||
return {};
|
||||
}
|
||||
|
||||
tl::expected<void, PacketError> tcp_server::HandleReceivePacket(packet &pkt)
|
||||
std::expected<void, PacketError> tcp_server::HandleReceivePacket(packet &pkt)
|
||||
{
|
||||
return SendPacket(pkt);
|
||||
}
|
||||
|
||||
tl::expected<void, PacketError> tcp_server::SendPacket(packet &pkt)
|
||||
std::expected<void, PacketError> tcp_server::SendPacket(packet &pkt)
|
||||
{
|
||||
if (pkt.Destination() == PLR_BROADCAST) {
|
||||
for (size_t i = 0; i < Players.size(); ++i) {
|
||||
if (i == pkt.Source() || !connections[i])
|
||||
continue;
|
||||
tl::expected<void, PacketError> result = StartSend(connections[i], pkt);
|
||||
std::expected<void, PacketError> result = StartSend(connections[i], pkt);
|
||||
if (!result.has_value())
|
||||
LogError("Failed to send packet {} to player {}: {}", static_cast<uint8_t>(pkt.Type()), i, result.error().what());
|
||||
}
|
||||
return {};
|
||||
}
|
||||
if (pkt.Destination() >= MAX_PLRS)
|
||||
return tl::make_unexpected(ServerError());
|
||||
return std::unexpected(ServerError());
|
||||
if (pkt.Destination() == pkt.Source() || !connections[pkt.Destination()])
|
||||
return {};
|
||||
return StartSend(connections[pkt.Destination()], pkt);
|
||||
}
|
||||
|
||||
tl::expected<void, PacketError> tcp_server::StartSend(const scc &con, packet &pkt)
|
||||
std::expected<void, PacketError> tcp_server::StartSend(const scc &con, packet &pkt)
|
||||
{
|
||||
return StartSend(con, pkt.Data(), 0);
|
||||
}
|
||||
|
||||
tl::expected<void, PacketError> tcp_server::StartSend(const scc &con, PacketError::ErrorCode errorCode)
|
||||
std::expected<void, PacketError> tcp_server::StartSend(const scc &con, PacketError::ErrorCode errorCode)
|
||||
{
|
||||
buffer_t pktData;
|
||||
pktData.push_back(static_cast<unsigned char>(errorCode));
|
||||
return StartSend(con, pktData, TcpErrorCodeFlags);
|
||||
}
|
||||
|
||||
tl::expected<void, PacketError> tcp_server::StartSend(const scc &con, buffer_t pktData, uint16_t flags)
|
||||
std::expected<void, PacketError> tcp_server::StartSend(const scc &con, buffer_t pktData, uint16_t flags)
|
||||
{
|
||||
tl::expected<buffer_t, PacketError> frame = frame_queue::MakeFrame(pktData, flags);
|
||||
std::expected<buffer_t, PacketError> frame = frame_queue::MakeFrame(pktData, flags);
|
||||
if (!frame.has_value())
|
||||
return tl::make_unexpected(frame.error());
|
||||
return std::unexpected(frame.error());
|
||||
std::unique_ptr<buffer_t> framePtr = std::make_unique<buffer_t>(*frame);
|
||||
const asio::mutable_buffer buf = asio::buffer(*framePtr);
|
||||
asio::async_write(con->socket, buf,
|
||||
@@ -279,7 +278,7 @@ void tcp_server::DropConnection(const scc &con)
|
||||
}
|
||||
connections[plr] = nullptr;
|
||||
|
||||
tl::expected<std::unique_ptr<packet>, PacketError> pkt
|
||||
std::expected<std::unique_ptr<packet>, PacketError> pkt
|
||||
= pktfty.make_packet<PT_DISCONNECT>(PLR_MASTER, PLR_BROADCAST,
|
||||
plr, leaveinfo_t::LEAVE_DROP);
|
||||
if (pkt.has_value()) {
|
||||
@@ -294,11 +293,11 @@ void tcp_server::RaiseIoHandlerError(const PacketError &error)
|
||||
ioHandlerResult.emplace(error);
|
||||
}
|
||||
|
||||
tl::expected<void, PacketError> tcp_server::CheckIoHandlerError()
|
||||
std::expected<void, PacketError> tcp_server::CheckIoHandlerError()
|
||||
{
|
||||
if (ioHandlerResult == std::nullopt)
|
||||
return {};
|
||||
tl::expected<void, PacketError> packetError = tl::make_unexpected(*ioHandlerResult);
|
||||
std::expected<void, PacketError> packetError = std::unexpected(*ioHandlerResult);
|
||||
ioHandlerResult = std::nullopt;
|
||||
return packetError;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <expected>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
@@ -13,8 +14,6 @@
|
||||
// the 3DS SDK.
|
||||
#include <fmt/core.h>
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include <asio/ts/buffer.hpp>
|
||||
#include <asio/ts/internet.hpp>
|
||||
#include <asio/ts/io_context.hpp>
|
||||
@@ -40,7 +39,7 @@ public:
|
||||
tcp_server(asio::io_context &ioc, const std::string &bindaddr,
|
||||
unsigned short port, packet_factory &pktfty);
|
||||
std::string LocalhostSelf();
|
||||
tl::expected<void, PacketError> CheckIoHandlerError();
|
||||
std::expected<void, PacketError> CheckIoHandlerError();
|
||||
void DisconnectNet(plr_t plr);
|
||||
void Close();
|
||||
virtual ~tcp_server();
|
||||
@@ -80,12 +79,12 @@ private:
|
||||
void HandleAccept(const scc &con, const asio::error_code &ec);
|
||||
void StartReceive(const scc &con);
|
||||
void HandleReceive(const scc &con, const asio::error_code &ec, size_t bytesRead);
|
||||
tl::expected<void, PacketError> HandleReceiveNewPlayer(const scc &con, packet &pkt);
|
||||
tl::expected<void, PacketError> HandleReceivePacket(packet &pkt);
|
||||
tl::expected<void, PacketError> SendPacket(packet &pkt);
|
||||
tl::expected<void, PacketError> StartSend(const scc &con, packet &pkt);
|
||||
tl::expected<void, PacketError> StartSend(const scc &con, PacketError::ErrorCode errorCode);
|
||||
tl::expected<void, PacketError> StartSend(const scc &con, buffer_t pktData, uint16_t flags);
|
||||
std::expected<void, PacketError> HandleReceiveNewPlayer(const scc &con, packet &pkt);
|
||||
std::expected<void, PacketError> HandleReceivePacket(packet &pkt);
|
||||
std::expected<void, PacketError> SendPacket(packet &pkt);
|
||||
std::expected<void, PacketError> StartSend(const scc &con, packet &pkt);
|
||||
std::expected<void, PacketError> StartSend(const scc &con, PacketError::ErrorCode errorCode);
|
||||
std::expected<void, PacketError> StartSend(const scc &con, buffer_t pktData, uint16_t flags);
|
||||
void HandleSend(const scc &con, const asio::error_code &ec, size_t bytesSent);
|
||||
void StartTimeout(const scc &con);
|
||||
void HandleTimeout(const scc &con, const asio::error_code &ec);
|
||||
|
||||
+7
-7
@@ -6,9 +6,9 @@
|
||||
#include "effects.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <string_view>
|
||||
|
||||
#include <expected.hpp>
|
||||
#include <magic_enum/magic_enum.hpp>
|
||||
|
||||
#include "data/file.hpp"
|
||||
@@ -126,7 +126,7 @@ SfxID RndSFX(SfxID psfx)
|
||||
}
|
||||
}
|
||||
|
||||
tl::expected<sfx_flag, std::string> ParseSfxFlag(std::string_view value)
|
||||
std::expected<sfx_flag, std::string> ParseSfxFlag(std::string_view value)
|
||||
{
|
||||
if (value == "Stream") return sfx_STREAM;
|
||||
if (value == "Misc") return sfx_MISC;
|
||||
@@ -135,7 +135,7 @@ tl::expected<sfx_flag, std::string> ParseSfxFlag(std::string_view value)
|
||||
if (value == "Rogue") return sfx_ROGUE;
|
||||
if (value == "Warrior") return sfx_WARRIOR;
|
||||
if (value == "Sorcerer") return sfx_SORCERER;
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
void LoadEffectsData()
|
||||
@@ -329,22 +329,22 @@ int GetSFXLength(SfxID nSFX)
|
||||
return sfx.pSnd->DSB.GetLength();
|
||||
}
|
||||
|
||||
tl::expected<HeroSpeech, std::string> ParseHeroSpeech(std::string_view value)
|
||||
std::expected<HeroSpeech, std::string> ParseHeroSpeech(std::string_view value)
|
||||
{
|
||||
const std::optional<HeroSpeech> enumValueOpt = magic_enum::enum_cast<HeroSpeech>(value);
|
||||
if (enumValueOpt.has_value()) {
|
||||
return enumValueOpt.value();
|
||||
}
|
||||
return tl::make_unexpected("Unknown enum value.");
|
||||
return std::unexpected("Unknown enum value.");
|
||||
}
|
||||
|
||||
tl::expected<SfxID, std::string> ParseSfxId(std::string_view value)
|
||||
std::expected<SfxID, std::string> ParseSfxId(std::string_view value)
|
||||
{
|
||||
const std::optional<SfxID> enumValueOpt = magic_enum::enum_cast<SfxID>(value);
|
||||
if (enumValueOpt.has_value()) {
|
||||
return enumValueOpt.value();
|
||||
}
|
||||
return tl::make_unexpected("Unknown enum value.");
|
||||
return std::unexpected("Unknown enum value.");
|
||||
}
|
||||
|
||||
} // namespace devilution
|
||||
|
||||
+3
-4
@@ -6,11 +6,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "engine/sound.h"
|
||||
#include "sound_effect_enums.h"
|
||||
|
||||
@@ -37,7 +36,7 @@ void ui_sound_init();
|
||||
void effects_play_sound(SfxID);
|
||||
int GetSFXLength(SfxID nSFX);
|
||||
|
||||
tl::expected<HeroSpeech, std::string> ParseHeroSpeech(std::string_view value);
|
||||
tl::expected<SfxID, std::string> ParseSfxId(std::string_view value);
|
||||
std::expected<HeroSpeech, std::string> ParseHeroSpeech(std::string_view value);
|
||||
std::expected<SfxID, std::string> ParseSfxId(std::string_view value);
|
||||
|
||||
} // namespace devilution
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Stubbed implementations of effects for the NOSOUND mode.
|
||||
#include "effects.h"
|
||||
|
||||
#include <expected.hpp>
|
||||
#include <expected>
|
||||
#include <magic_enum/magic_enum.hpp>
|
||||
|
||||
#include "engine/random.hpp"
|
||||
@@ -50,22 +50,22 @@ void ui_sound_init() { }
|
||||
void effects_play_sound(SfxID id) { }
|
||||
int GetSFXLength(SfxID nSFX) { return 0; }
|
||||
|
||||
tl::expected<HeroSpeech, std::string> ParseHeroSpeech(std::string_view value)
|
||||
std::expected<HeroSpeech, std::string> ParseHeroSpeech(std::string_view value)
|
||||
{
|
||||
const std::optional<HeroSpeech> enumValueOpt = magic_enum::enum_cast<HeroSpeech>(value);
|
||||
if (enumValueOpt.has_value()) {
|
||||
return enumValueOpt.value();
|
||||
}
|
||||
return tl::make_unexpected("Unknown enum value.");
|
||||
return std::unexpected("Unknown enum value.");
|
||||
}
|
||||
|
||||
tl::expected<SfxID, std::string> ParseSfxId(std::string_view value)
|
||||
std::expected<SfxID, std::string> ParseSfxId(std::string_view value)
|
||||
{
|
||||
const std::optional<SfxID> enumValueOpt = magic_enum::enum_cast<SfxID>(value);
|
||||
if (enumValueOpt.has_value()) {
|
||||
return enumValueOpt.value();
|
||||
}
|
||||
return tl::make_unexpected("Unknown enum value.");
|
||||
return std::unexpected("Unknown enum value.");
|
||||
}
|
||||
|
||||
} // namespace devilution
|
||||
|
||||
+20
-19
@@ -4,6 +4,7 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <expected>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string_view>
|
||||
@@ -311,11 +312,11 @@ SDL_IOStream *OpenAssetAsSdlRwOps(std::string_view filename, bool threadsafe)
|
||||
#endif
|
||||
}
|
||||
|
||||
tl::expected<AssetData, std::string> LoadAsset(std::string_view path)
|
||||
std::expected<AssetData, std::string> LoadAsset(std::string_view path)
|
||||
{
|
||||
AssetRef ref = FindAsset(path);
|
||||
if (!ref.ok()) {
|
||||
return tl::make_unexpected(StrCat("Asset not found: ", path));
|
||||
return std::unexpected(StrCat("Asset not found: ", path));
|
||||
}
|
||||
|
||||
const size_t size = ref.size();
|
||||
@@ -323,21 +324,21 @@ tl::expected<AssetData, std::string> LoadAsset(std::string_view path)
|
||||
|
||||
AssetHandle handle = OpenAsset(std::move(ref));
|
||||
if (!handle.ok()) {
|
||||
return tl::make_unexpected(StrCat("Failed to open asset: ", path, "\n", handle.error()));
|
||||
return std::unexpected(StrCat("Failed to open asset: ", path, "\n", handle.error()));
|
||||
}
|
||||
|
||||
if (size > 0 && !handle.read(data.get(), size)) {
|
||||
return tl::make_unexpected(StrCat("Read failed: ", path, "\n", handle.error()));
|
||||
return std::unexpected(StrCat("Read failed: ", path, "\n", handle.error()));
|
||||
}
|
||||
|
||||
return AssetData { std::move(data), size };
|
||||
}
|
||||
|
||||
tl::expected<AssetData, std::string> LoadIntegralAsset(std::string_view path)
|
||||
std::expected<AssetData, std::string> LoadIntegralAsset(std::string_view path)
|
||||
{
|
||||
AssetRef ref = FindAsset(path);
|
||||
if (!ref.ok()) {
|
||||
return tl::make_unexpected(StrCat("Asset not found: ", path));
|
||||
return std::unexpected(StrCat("Asset not found: ", path));
|
||||
}
|
||||
|
||||
const size_t size = ref.size();
|
||||
@@ -345,11 +346,11 @@ tl::expected<AssetData, std::string> LoadIntegralAsset(std::string_view path)
|
||||
|
||||
AssetHandle handle = OpenIntegralAsset(std::move(ref));
|
||||
if (!handle.ok()) {
|
||||
return tl::make_unexpected(StrCat("Failed to open asset: ", path, "\n", handle.error()));
|
||||
return std::unexpected(StrCat("Failed to open asset: ", path, "\n", handle.error()));
|
||||
}
|
||||
|
||||
if (size > 0 && !handle.read(data.get(), size)) {
|
||||
return tl::make_unexpected(StrCat("Read failed: ", path, "\n", handle.error()));
|
||||
return std::unexpected(StrCat("Read failed: ", path, "\n", handle.error()));
|
||||
}
|
||||
|
||||
return AssetData { std::move(data), size };
|
||||
@@ -415,7 +416,7 @@ bool LoadMPQ(std::span<const std::string> paths, std::string_view mpqName, int p
|
||||
mpqAbsPath = StrCat(path, mpqName, ext);
|
||||
if (!FileExists(mpqAbsPath))
|
||||
continue;
|
||||
tl::expected<MpqArchive, std::string> archive = MpqArchive::Open(mpqAbsPath.c_str());
|
||||
std::expected<MpqArchive, std::string> archive = MpqArchive::Open(mpqAbsPath.c_str());
|
||||
if (!archive.has_value()) {
|
||||
foundButFailed = true;
|
||||
LogError("Error {}: {}", archive.error(), mpqAbsPath);
|
||||
@@ -607,22 +608,22 @@ void UnloadModArchives()
|
||||
#ifndef UNPACKED_MPQS
|
||||
namespace {
|
||||
|
||||
tl::expected<ModManifest, int32_t> ReadPackedModManifestFrom(MpqArchive &archive)
|
||||
std::expected<ModManifest, int32_t> ReadPackedModManifestFrom(MpqArchive &archive)
|
||||
{
|
||||
constexpr std::string_view ManifestName = "manifest.ini";
|
||||
if (!archive.HasFile(ManifestName))
|
||||
return tl::make_unexpected(0);
|
||||
return std::unexpected(0);
|
||||
|
||||
size_t fileSize = 0;
|
||||
int32_t error = 0;
|
||||
std::unique_ptr<std::byte[]> data = archive.ReadFile(ManifestName, fileSize, error);
|
||||
if (data == nullptr)
|
||||
return tl::make_unexpected(error);
|
||||
return std::unexpected(error);
|
||||
|
||||
return ParseModManifest(std::string_view(reinterpret_cast<const char *>(data.get()), fileSize));
|
||||
}
|
||||
|
||||
tl::expected<ModManifest, int32_t> ReadPackedModManifest(std::span<const std::string> paths, std::string_view modname)
|
||||
std::expected<ModManifest, int32_t> ReadPackedModManifest(std::span<const std::string> paths, std::string_view modname)
|
||||
{
|
||||
const std::string mpqName = StrCat("mods" DIRECTORY_SEPARATOR_STR, modname);
|
||||
std::string mpqAbsPath;
|
||||
@@ -630,12 +631,12 @@ tl::expected<ModManifest, int32_t> ReadPackedModManifest(std::span<const std::st
|
||||
mpqAbsPath = StrCat(path, mpqName, ".mpq");
|
||||
if (!FileExists(mpqAbsPath))
|
||||
continue;
|
||||
tl::expected<MpqArchive, std::string> archive = MpqArchive::Open(mpqAbsPath.c_str());
|
||||
std::expected<MpqArchive, std::string> archive = MpqArchive::Open(mpqAbsPath.c_str());
|
||||
if (!archive.has_value())
|
||||
return tl::make_unexpected(0);
|
||||
return std::unexpected(0);
|
||||
return ReadPackedModManifestFrom(*archive);
|
||||
}
|
||||
return tl::make_unexpected(0);
|
||||
return std::unexpected(0);
|
||||
}
|
||||
|
||||
// Reads the mod's `manifest.ini` from its own archive (registered at `priority`) and
|
||||
@@ -647,7 +648,7 @@ void ReadLoadedModManifest(ModIdentifier &mod, int priority)
|
||||
if (it == MpqArchives.end())
|
||||
return;
|
||||
MpqArchive &archive = it->second;
|
||||
tl::expected<ModManifest, int32_t> manifest = ReadPackedModManifestFrom(archive);
|
||||
std::expected<ModManifest, int32_t> manifest = ReadPackedModManifestFrom(archive);
|
||||
if (manifest.has_value())
|
||||
mod.manifest = std::move(*manifest);
|
||||
else if (manifest.error() != 0)
|
||||
@@ -659,7 +660,7 @@ void ReadLoadedModManifest(ModIdentifier &mod, int priority)
|
||||
// the mod has no packed archive, no manifest, or an unreadable one.
|
||||
std::vector<std::string> ReadPackedModRequiredMods(std::span<const std::string> paths, std::string_view modname)
|
||||
{
|
||||
tl::expected<ModManifest, int32_t> manifest = ReadPackedModManifest(paths, modname);
|
||||
std::expected<ModManifest, int32_t> manifest = ReadPackedModManifest(paths, modname);
|
||||
if (!manifest.has_value())
|
||||
return {};
|
||||
return std::move(manifest->requiredMods);
|
||||
@@ -693,7 +694,7 @@ ModManifest ReadModManifestByName(std::string_view name)
|
||||
|
||||
#ifndef UNPACKED_MPQS
|
||||
// Packed mod archive.
|
||||
tl::expected<ModManifest, int32_t> manifest = ReadPackedModManifest(searchPaths, name);
|
||||
std::expected<ModManifest, int32_t> manifest = ReadPackedModManifest(searchPaths, name);
|
||||
if (manifest.has_value())
|
||||
return std::move(*manifest);
|
||||
#endif
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <expected>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <span>
|
||||
@@ -17,8 +18,6 @@
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "appfat.h"
|
||||
@@ -298,8 +297,8 @@ struct AssetData {
|
||||
}
|
||||
};
|
||||
|
||||
tl::expected<AssetData, std::string> LoadAsset(std::string_view path);
|
||||
tl::expected<AssetData, std::string> LoadIntegralAsset(std::string_view path);
|
||||
std::expected<AssetData, std::string> LoadAsset(std::string_view path);
|
||||
std::expected<AssetData, std::string> LoadIntegralAsset(std::string_view path);
|
||||
|
||||
#ifdef UNPACKED_MPQS
|
||||
using MpqArchiveT = std::string;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
@@ -9,8 +10,6 @@
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "appfat.h"
|
||||
#include "mpq/mpq_common.hpp"
|
||||
#include "utils/status_macros.hpp"
|
||||
@@ -25,7 +24,7 @@
|
||||
|
||||
namespace devilution {
|
||||
|
||||
tl::expected<OwnedClxSpriteListOrSheet, std::string> LoadCelListOrSheetWithStatus(const char *pszName, PointerOrValue<uint16_t> widthOrWidths)
|
||||
std::expected<OwnedClxSpriteListOrSheet, std::string> LoadCelListOrSheetWithStatus(const char *pszName, PointerOrValue<uint16_t> widthOrWidths)
|
||||
{
|
||||
char path[MaxMpqPathSize];
|
||||
*BufCopy(path, pszName, DEVILUTIONX_CEL_EXT) = '\0';
|
||||
@@ -43,7 +42,7 @@ tl::expected<OwnedClxSpriteListOrSheet, std::string> LoadCelListOrSheetWithStatu
|
||||
|
||||
OwnedClxSpriteListOrSheet LoadCelListOrSheet(const char *pszName, PointerOrValue<uint16_t> widthOrWidths)
|
||||
{
|
||||
tl::expected<OwnedClxSpriteListOrSheet, std::string> result = LoadCelListOrSheetWithStatus(pszName, widthOrWidths);
|
||||
std::expected<OwnedClxSpriteListOrSheet, std::string> result = LoadCelListOrSheetWithStatus(pszName, widthOrWidths);
|
||||
if (DVL_PREDICT_FALSE(!result.has_value())) app_fatal(result.error());
|
||||
return std::move(result).value();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <string>
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "engine/clx_sprite.hpp"
|
||||
#include "utils/pointer_value_union.hpp"
|
||||
#include "utils/status_macros.hpp"
|
||||
@@ -17,7 +16,7 @@
|
||||
|
||||
namespace devilution {
|
||||
|
||||
tl::expected<OwnedClxSpriteListOrSheet, std::string> LoadCelListOrSheetWithStatus(const char *pszName, PointerOrValue<uint16_t> widthOrWidths);
|
||||
std::expected<OwnedClxSpriteListOrSheet, std::string> LoadCelListOrSheetWithStatus(const char *pszName, PointerOrValue<uint16_t> widthOrWidths);
|
||||
|
||||
OwnedClxSpriteListOrSheet LoadCelListOrSheet(const char *pszName, PointerOrValue<uint16_t> widthOrWidths);
|
||||
|
||||
@@ -28,13 +27,13 @@ inline OwnedClxSpriteList LoadCel(const char *pszName, uint16_t width)
|
||||
|
||||
inline OptionalOwnedClxSpriteList LoadOptionalCel(const char *pszName, uint16_t width)
|
||||
{
|
||||
tl::expected<OwnedClxSpriteListOrSheet, std::string> result = LoadCelListOrSheetWithStatus(pszName, PointerOrValue<uint16_t> { width });
|
||||
std::expected<OwnedClxSpriteListOrSheet, std::string> result = LoadCelListOrSheetWithStatus(pszName, PointerOrValue<uint16_t> { width });
|
||||
if (!result.has_value())
|
||||
return std::nullopt;
|
||||
return (*std::move(result)).list();
|
||||
}
|
||||
|
||||
inline tl::expected<OwnedClxSpriteList, std::string> LoadCelWithStatus(const char *pszName, uint16_t width)
|
||||
inline std::expected<OwnedClxSpriteList, std::string> LoadCelWithStatus(const char *pszName, uint16_t width)
|
||||
{
|
||||
ASSIGN_OR_RETURN(OwnedClxSpriteListOrSheet result, LoadCelListOrSheetWithStatus(pszName, PointerOrValue<uint16_t> { width }));
|
||||
return std::move(result).list();
|
||||
@@ -47,13 +46,13 @@ inline OwnedClxSpriteList LoadCel(const char *pszName, const uint16_t *widths)
|
||||
|
||||
inline OptionalOwnedClxSpriteList LoadOptionalCel(const char *pszName, const uint16_t *widths)
|
||||
{
|
||||
tl::expected<OwnedClxSpriteListOrSheet, std::string> result = LoadCelListOrSheetWithStatus(pszName, PointerOrValue<uint16_t> { widths });
|
||||
std::expected<OwnedClxSpriteListOrSheet, std::string> result = LoadCelListOrSheetWithStatus(pszName, PointerOrValue<uint16_t> { widths });
|
||||
if (!result.has_value())
|
||||
return std::nullopt;
|
||||
return (*std::move(result)).list();
|
||||
}
|
||||
|
||||
inline tl::expected<OwnedClxSpriteList, std::string> LoadCelWithStatus(const char *pszName, const uint16_t *widths)
|
||||
inline std::expected<OwnedClxSpriteList, std::string> LoadCelWithStatus(const char *pszName, const uint16_t *widths)
|
||||
{
|
||||
ASSIGN_OR_RETURN(OwnedClxSpriteListOrSheet result, LoadCelListOrSheetWithStatus(pszName, PointerOrValue<uint16_t> { widths }));
|
||||
return std::move(result).list();
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
#include "engine/load_cl2.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "mpq/mpq_common.hpp"
|
||||
#include "utils/status_macros.hpp"
|
||||
#include "utils/str_cat.hpp"
|
||||
@@ -19,7 +18,7 @@
|
||||
|
||||
namespace devilution {
|
||||
|
||||
tl::expected<OwnedClxSpriteListOrSheet, std::string> LoadCl2ListOrSheetWithStatus(const char *pszName, PointerOrValue<uint16_t> widthOrWidths)
|
||||
std::expected<OwnedClxSpriteListOrSheet, std::string> LoadCl2ListOrSheetWithStatus(const char *pszName, PointerOrValue<uint16_t> widthOrWidths)
|
||||
{
|
||||
char path[MaxMpqPathSize];
|
||||
*BufCopy(path, pszName, DEVILUTIONX_CL2_EXT) = '\0';
|
||||
@@ -34,7 +33,7 @@ tl::expected<OwnedClxSpriteListOrSheet, std::string> LoadCl2ListOrSheetWithStatu
|
||||
|
||||
OwnedClxSpriteListOrSheet LoadCl2ListOrSheet(const char *pszName, PointerOrValue<uint16_t> widthOrWidths)
|
||||
{
|
||||
tl::expected<OwnedClxSpriteListOrSheet, std::string> result = LoadCl2ListOrSheetWithStatus(pszName, widthOrWidths);
|
||||
std::expected<OwnedClxSpriteListOrSheet, std::string> result = LoadCl2ListOrSheetWithStatus(pszName, widthOrWidths);
|
||||
if (!result.has_value()) app_fatal(result.error());
|
||||
return std::move(result).value();
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <expected>
|
||||
#include <string>
|
||||
|
||||
#include <expected.hpp>
|
||||
#include <function_ref.hpp>
|
||||
|
||||
#include "appfat.h"
|
||||
@@ -29,11 +29,11 @@
|
||||
|
||||
namespace devilution {
|
||||
|
||||
tl::expected<OwnedClxSpriteListOrSheet, std::string> LoadCl2ListOrSheetWithStatus(const char *pszName, PointerOrValue<uint16_t> widthOrWidths);
|
||||
std::expected<OwnedClxSpriteListOrSheet, std::string> LoadCl2ListOrSheetWithStatus(const char *pszName, PointerOrValue<uint16_t> widthOrWidths);
|
||||
OwnedClxSpriteListOrSheet LoadCl2ListOrSheet(const char *pszName, PointerOrValue<uint16_t> widthOrWidths);
|
||||
|
||||
template <size_t MaxCount>
|
||||
tl::expected<OwnedClxSpriteSheet, std::string> LoadMultipleCl2Sheet(tl::function_ref<const char *(size_t)> filenames, size_t count, uint16_t width)
|
||||
std::expected<OwnedClxSpriteSheet, std::string> LoadMultipleCl2Sheet(tl::function_ref<const char *(size_t)> filenames, size_t count, uint16_t width)
|
||||
{
|
||||
StaticVector<std::array<char, MaxMpqPathSize>, MaxCount> paths;
|
||||
StaticVector<AssetRef, MaxCount> files;
|
||||
@@ -76,7 +76,7 @@ tl::expected<OwnedClxSpriteSheet, std::string> LoadMultipleCl2Sheet(tl::function
|
||||
#endif
|
||||
}
|
||||
|
||||
inline tl::expected<OwnedClxSpriteList, std::string> LoadCl2WithStatus(const char *pszName, uint16_t width)
|
||||
inline std::expected<OwnedClxSpriteList, std::string> LoadCl2WithStatus(const char *pszName, uint16_t width)
|
||||
{
|
||||
ASSIGN_OR_RETURN(OwnedClxSpriteListOrSheet result, LoadCl2ListOrSheetWithStatus(pszName, PointerOrValue<uint16_t> { width }));
|
||||
return std::move(result).list();
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#include <expected.hpp>
|
||||
#include <expected>
|
||||
|
||||
#include "appfat.h"
|
||||
#include "engine/assets.hpp"
|
||||
@@ -26,17 +25,17 @@ OptionalOwnedClxSpriteListOrSheet LoadOptionalClxListOrSheet(const char *path)
|
||||
return OwnedClxSpriteListOrSheet::FromBuffer(std::move(data), size);
|
||||
}
|
||||
|
||||
tl::expected<OwnedClxSpriteListOrSheet, std::string> LoadClxListOrSheetWithStatus(const char *path)
|
||||
std::expected<OwnedClxSpriteListOrSheet, std::string> LoadClxListOrSheetWithStatus(const char *path)
|
||||
{
|
||||
size_t size;
|
||||
tl::expected<std::unique_ptr<uint8_t[]>, std::string> data = LoadFileInMemWithStatus<uint8_t>(path, &size);
|
||||
if (!data.has_value()) return tl::make_unexpected(std::move(data).error());
|
||||
std::expected<std::unique_ptr<uint8_t[]>, std::string> data = LoadFileInMemWithStatus<uint8_t>(path, &size);
|
||||
if (!data.has_value()) return std::unexpected(std::move(data).error());
|
||||
return OwnedClxSpriteListOrSheet::FromBuffer(std::move(data).value(), size);
|
||||
}
|
||||
|
||||
OwnedClxSpriteListOrSheet LoadClxListOrSheet(const char *path)
|
||||
{
|
||||
tl::expected<OwnedClxSpriteListOrSheet, std::string> result = LoadClxListOrSheetWithStatus(path);
|
||||
std::expected<OwnedClxSpriteListOrSheet, std::string> result = LoadClxListOrSheetWithStatus(path);
|
||||
if (!result.has_value()) app_fatal(result.error());
|
||||
return std::move(result).value();
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <expected>
|
||||
#include <string>
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "clx_sprite.hpp"
|
||||
#include "utils/status_macros.hpp"
|
||||
|
||||
@@ -11,14 +10,14 @@ namespace devilution {
|
||||
|
||||
OwnedClxSpriteListOrSheet LoadClxListOrSheet(const char *path);
|
||||
|
||||
tl::expected<OwnedClxSpriteListOrSheet, std::string> LoadClxListOrSheetWithStatus(const char *path);
|
||||
std::expected<OwnedClxSpriteListOrSheet, std::string> LoadClxListOrSheetWithStatus(const char *path);
|
||||
|
||||
inline OwnedClxSpriteList LoadClx(const char *path)
|
||||
{
|
||||
return LoadClxListOrSheet(path).list();
|
||||
}
|
||||
|
||||
inline tl::expected<OwnedClxSpriteList, std::string> LoadClxWithStatus(const char *path)
|
||||
inline std::expected<OwnedClxSpriteList, std::string> LoadClxWithStatus(const char *path)
|
||||
{
|
||||
ASSIGN_OR_RETURN(OwnedClxSpriteListOrSheet result, LoadClxListOrSheetWithStatus(path));
|
||||
return std::move(result).list();
|
||||
|
||||
+20
-21
@@ -4,10 +4,9 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <expected>
|
||||
#include <memory>
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "appfat.h"
|
||||
#include "engine/assets.hpp"
|
||||
#include "mpq/mpq_common.hpp"
|
||||
@@ -17,35 +16,35 @@
|
||||
namespace devilution {
|
||||
|
||||
template <typename T>
|
||||
tl::expected<void, std::string> LoadFileInMemWithStatus(const char *path, T *data)
|
||||
std::expected<void, std::string> LoadFileInMemWithStatus(const char *path, T *data)
|
||||
{
|
||||
size_t size;
|
||||
AssetHandle handle = OpenAsset(path, size);
|
||||
if (!handle.ok()) {
|
||||
return tl::make_unexpected(FailedToOpenFileErrorMessage(path, handle.error()));
|
||||
return std::unexpected(FailedToOpenFileErrorMessage(path, handle.error()));
|
||||
}
|
||||
if ((size % sizeof(T)) != 0) {
|
||||
return tl::make_unexpected(StrCat("File size does not align with type\n", path));
|
||||
return std::unexpected(StrCat("File size does not align with type\n", path));
|
||||
}
|
||||
if (!handle.read(data, size)) {
|
||||
return tl::make_unexpected("handle.read failed");
|
||||
return std::unexpected("handle.read failed");
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
tl::expected<void, std::string> LoadIntegralFileInMemWithStatus(const char *path, T *data)
|
||||
std::expected<void, std::string> LoadIntegralFileInMemWithStatus(const char *path, T *data)
|
||||
{
|
||||
size_t size;
|
||||
AssetHandle handle = OpenIntegralAsset(path, size);
|
||||
if (!handle.ok()) {
|
||||
return tl::make_unexpected(FailedToOpenFileErrorMessage(path, handle.error()));
|
||||
return std::unexpected(FailedToOpenFileErrorMessage(path, handle.error()));
|
||||
}
|
||||
if ((size % sizeof(T)) != 0) {
|
||||
return tl::make_unexpected(StrCat("File size does not align with type\n", path));
|
||||
return std::unexpected(StrCat("File size does not align with type\n", path));
|
||||
}
|
||||
if (!handle.read(data, size)) {
|
||||
return tl::make_unexpected("handle.read failed");
|
||||
return std::unexpected("handle.read failed");
|
||||
}
|
||||
return {};
|
||||
}
|
||||
@@ -53,19 +52,19 @@ tl::expected<void, std::string> LoadIntegralFileInMemWithStatus(const char *path
|
||||
template <typename T>
|
||||
void LoadFileInMem(const char *path, T *data)
|
||||
{
|
||||
const tl::expected<void, std::string> result = LoadFileInMemWithStatus<T>(path, data);
|
||||
const std::expected<void, std::string> result = LoadFileInMemWithStatus<T>(path, data);
|
||||
if (!result.has_value()) app_fatal(result.error());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
tl::expected<void, std::string> LoadFileInMemWithStatus(const char *path, T *data, std::size_t count)
|
||||
std::expected<void, std::string> LoadFileInMemWithStatus(const char *path, T *data, std::size_t count)
|
||||
{
|
||||
AssetHandle handle = OpenAsset(path);
|
||||
if (!handle.ok()) {
|
||||
return tl::make_unexpected(FailedToOpenFileErrorMessage(path, handle.error()));
|
||||
return std::unexpected(FailedToOpenFileErrorMessage(path, handle.error()));
|
||||
}
|
||||
if (!handle.read(data, count * sizeof(T))) {
|
||||
return tl::make_unexpected("handle.read failed");
|
||||
return std::unexpected("handle.read failed");
|
||||
}
|
||||
return {};
|
||||
}
|
||||
@@ -73,7 +72,7 @@ tl::expected<void, std::string> LoadFileInMemWithStatus(const char *path, T *dat
|
||||
template <typename T>
|
||||
void LoadFileInMem(const char *path, T *data, std::size_t count)
|
||||
{
|
||||
tl::expected<void, std::string> result = LoadFileInMemWithStatus<T>(path, data, count);
|
||||
std::expected<void, std::string> result = LoadFileInMemWithStatus<T>(path, data, count);
|
||||
if (!result.has_value()) app_fatal(result.error());
|
||||
}
|
||||
|
||||
@@ -85,7 +84,7 @@ bool LoadOptionalFileInMem(const char *path, T *data, std::size_t count)
|
||||
}
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
tl::expected<void, std::string> LoadFileInMemWithStatus(const char *path, std::array<T, N> &data)
|
||||
std::expected<void, std::string> LoadFileInMemWithStatus(const char *path, std::array<T, N> &data)
|
||||
{
|
||||
return LoadFileInMemWithStatus(path, data.data(), N);
|
||||
}
|
||||
@@ -97,15 +96,15 @@ void LoadFileInMem(const char *path, std::array<T, N> &data)
|
||||
}
|
||||
|
||||
template <typename T = std::byte>
|
||||
tl::expected<std::unique_ptr<T[]>, std::string> LoadFileInMemWithStatus(const char *path, std::size_t *numRead = nullptr)
|
||||
std::expected<std::unique_ptr<T[]>, std::string> LoadFileInMemWithStatus(const char *path, std::size_t *numRead = nullptr)
|
||||
{
|
||||
size_t size;
|
||||
AssetHandle handle = OpenAsset(path, size);
|
||||
if (!handle.ok()) {
|
||||
return tl::make_unexpected(FailedToOpenFileErrorMessage(path, handle.error()));
|
||||
return std::unexpected(FailedToOpenFileErrorMessage(path, handle.error()));
|
||||
}
|
||||
if ((size % sizeof(T)) != 0) {
|
||||
return tl::make_unexpected(StrCat("File size does not align with type\n", path));
|
||||
return std::unexpected(StrCat("File size does not align with type\n", path));
|
||||
}
|
||||
|
||||
if (numRead != nullptr)
|
||||
@@ -113,7 +112,7 @@ tl::expected<std::unique_ptr<T[]>, std::string> LoadFileInMemWithStatus(const ch
|
||||
|
||||
std::unique_ptr<T[]> buf { new T[size / sizeof(T)] };
|
||||
if (!handle.read(buf.get(), size)) {
|
||||
return tl::make_unexpected("handle.read failed");
|
||||
return std::unexpected("handle.read failed");
|
||||
}
|
||||
return { std::move(buf) };
|
||||
}
|
||||
@@ -127,7 +126,7 @@ tl::expected<std::unique_ptr<T[]>, std::string> LoadFileInMemWithStatus(const ch
|
||||
template <typename T = std::byte>
|
||||
std::unique_ptr<T[]> LoadFileInMem(const char *path, std::size_t *numRead = nullptr)
|
||||
{
|
||||
tl::expected<std::unique_ptr<T[]>, std::string> result = LoadFileInMemWithStatus<T>(path, numRead);
|
||||
std::expected<std::unique_ptr<T[]>, std::string> result = LoadFileInMemWithStatus<T>(path, numRead);
|
||||
if (!result.has_value()) app_fatal(result.error());
|
||||
return std::move(result).value();
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
@@ -23,7 +24,6 @@
|
||||
#include <Aulib/Stream.h>
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "appfat.h"
|
||||
#include "engine/assets.hpp"
|
||||
@@ -64,7 +64,7 @@ std::string GetMp3Path(const char *path)
|
||||
return mp3Path;
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> LoadAudioFile(const char *path, bool stream, SoundSample &result)
|
||||
std::expected<void, std::string> LoadAudioFile(const char *path, bool stream, SoundSample &result)
|
||||
{
|
||||
bool isMp3 = true;
|
||||
std::string foundPath = GetMp3Path(path);
|
||||
@@ -75,7 +75,7 @@ tl::expected<void, std::string> LoadAudioFile(const char *path, bool stream, Sou
|
||||
isMp3 = false;
|
||||
}
|
||||
if (!ref.ok()) {
|
||||
return tl::make_unexpected(StrCat("Audio file not found\n", path, "\n", SDL_GetError(), "\n" __FILE__ ":", __LINE__));
|
||||
return std::unexpected(StrCat("Audio file not found\n", path, "\n", SDL_GetError(), "\n" __FILE__ ":", __LINE__));
|
||||
}
|
||||
|
||||
#ifdef STREAM_ALL_AUDIO_MIN_FILE_SIZE
|
||||
@@ -92,7 +92,7 @@ tl::expected<void, std::string> LoadAudioFile(const char *path, bool stream, Sou
|
||||
|
||||
if (stream) {
|
||||
if (result.SetChunkStream(foundPath, isMp3, /*logErrors=*/true) != 0) {
|
||||
return tl::make_unexpected(StrCat("Failed to load audio file\n", foundPath, "\n", SDL_GetError(), "\n" __FILE__ ":", __LINE__));
|
||||
return std::unexpected(StrCat("Failed to load audio file\n", foundPath, "\n", SDL_GetError(), "\n" __FILE__ ":", __LINE__));
|
||||
}
|
||||
} else {
|
||||
#if !defined(STREAM_ALL_AUDIO_MIN_FILE_SIZE) || STREAM_ALL_AUDIO_MIN_FILE_SIZE == 0
|
||||
@@ -100,15 +100,15 @@ tl::expected<void, std::string> LoadAudioFile(const char *path, bool stream, Sou
|
||||
#endif
|
||||
AssetHandle handle = OpenAsset(std::move(ref));
|
||||
if (!handle.ok()) {
|
||||
return tl::make_unexpected(StrCat("Failed to load audio file\n", foundPath, "\n", SDL_GetError(), "\n" __FILE__ ":", __LINE__));
|
||||
return std::unexpected(StrCat("Failed to load audio file\n", foundPath, "\n", SDL_GetError(), "\n" __FILE__ ":", __LINE__));
|
||||
}
|
||||
auto waveFile = MakeArraySharedPtr<std::uint8_t>(size);
|
||||
if (!handle.read(waveFile.get(), size)) {
|
||||
return tl::make_unexpected(StrCat("Failed to read file\n", foundPath, ": ", SDL_GetError(), __FILE__ ":", __LINE__));
|
||||
return std::unexpected(StrCat("Failed to read file\n", foundPath, ": ", SDL_GetError(), __FILE__ ":", __LINE__));
|
||||
}
|
||||
const int error = result.SetChunk(waveFile, size, isMp3);
|
||||
if (error != 0) {
|
||||
return tl::make_unexpected(SDL_GetError());
|
||||
return std::unexpected(SDL_GetError());
|
||||
}
|
||||
}
|
||||
return {};
|
||||
@@ -224,7 +224,7 @@ void snd_play_snd(TSnd *pSnd, int lVolume, int lPan, int userVolume)
|
||||
pSnd->start_tc = tc;
|
||||
}
|
||||
|
||||
tl::expected<std::unique_ptr<TSnd>, std::string> SoundFileLoadWithStatus(const char *path, bool stream)
|
||||
std::expected<std::unique_ptr<TSnd>, std::string> SoundFileLoadWithStatus(const char *path, bool stream)
|
||||
{
|
||||
auto snd = std::make_unique<TSnd>();
|
||||
snd->start_tc = SDL_GetTicks() - 80 - 1;
|
||||
@@ -236,7 +236,7 @@ tl::expected<std::unique_ptr<TSnd>, std::string> SoundFileLoadWithStatus(const c
|
||||
|
||||
std::unique_ptr<TSnd> sound_file_load(const char *path, bool stream)
|
||||
{
|
||||
tl::expected<std::unique_ptr<TSnd>, std::string> result = SoundFileLoadWithStatus(path, stream);
|
||||
std::expected<std::unique_ptr<TSnd>, std::string> result = SoundFileLoadWithStatus(path, stream);
|
||||
if (!result.has_value()) app_fatal(result.error());
|
||||
return std::move(result).value();
|
||||
}
|
||||
|
||||
@@ -6,12 +6,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "levels/gendung.h"
|
||||
#include "utils/attributes.h"
|
||||
|
||||
@@ -69,7 +68,7 @@ extern _music_id sgnMusicTrack;
|
||||
void ClearDuplicateSounds();
|
||||
void snd_play_snd(TSnd *pSnd, int lVolume, int lPan, int userVolume);
|
||||
std::unique_ptr<TSnd> sound_file_load(const char *path, bool stream = false);
|
||||
tl::expected<std::unique_ptr<TSnd>, std::string> SoundFileLoadWithStatus(const char *path, bool stream = false);
|
||||
std::expected<std::unique_ptr<TSnd>, std::string> SoundFileLoadWithStatus(const char *path, bool stream = false);
|
||||
void snd_init();
|
||||
void snd_deinit();
|
||||
_music_id GetLevelMusic(dungeon_type dungeonType);
|
||||
|
||||
@@ -11,7 +11,7 @@ _music_id sgnMusicTrack = NUM_MUSIC;
|
||||
void ClearDuplicateSounds() { }
|
||||
void snd_play_snd(TSnd *pSnd, int lVolume, int lPan, int userVolume) { }
|
||||
std::unique_ptr<TSnd> sound_file_load(const char *path, bool stream) { return nullptr; }
|
||||
tl::expected<std::unique_ptr<TSnd>, std::string> SoundFileLoadWithStatus(const char *path, bool stream) { return nullptr; }
|
||||
std::expected<std::unique_ptr<TSnd>, std::string> SoundFileLoadWithStatus(const char *path, bool stream) { return nullptr; }
|
||||
TSnd::~TSnd() { }
|
||||
void snd_init() { }
|
||||
void snd_deinit() { }
|
||||
|
||||
+1
-1
@@ -309,7 +309,7 @@ void gamemenu_load_game(bool /*bActivate*/)
|
||||
DeactivateVirtualGamepad();
|
||||
FreeVirtualGamepadTextures();
|
||||
#endif
|
||||
if (tl::expected<void, std::string> result = LoadGame(false); !result.has_value()) {
|
||||
if (std::expected<void, std::string> result = LoadGame(false); !result.has_value()) {
|
||||
app_fatal(result.error());
|
||||
}
|
||||
#if !defined(USE_SDL1) && !defined(__vita__)
|
||||
|
||||
+3
-4
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
@@ -20,8 +21,6 @@
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "control/control.hpp"
|
||||
#include "controls/input.h"
|
||||
#include "engine/clx_sprite.hpp"
|
||||
@@ -317,7 +316,7 @@ void DoLoad(interface_mode uMsg)
|
||||
IncProgress();
|
||||
|
||||
Player &myPlayer = *MyPlayer;
|
||||
tl::expected<void, std::string> loadResult;
|
||||
std::expected<void, std::string> loadResult;
|
||||
switch (uMsg) {
|
||||
case WM_DIABLOADGAME:
|
||||
IncProgress(2);
|
||||
@@ -464,7 +463,7 @@ void DoLoad(interface_mode uMsg)
|
||||
if (loadResult.has_value()) IncProgress();
|
||||
break;
|
||||
default:
|
||||
loadResult = tl::make_unexpected<std::string>("Unknown progress mode");
|
||||
loadResult = std::unexpected<std::string>("Unknown progress mode");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <memory>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
@@ -9,7 +10,6 @@
|
||||
#include <vector>
|
||||
|
||||
#include <ankerl/unordered_dense.h>
|
||||
#include <expected.hpp>
|
||||
#include <magic_enum/magic_enum.hpp>
|
||||
|
||||
#include "engine/clx_sprite.hpp"
|
||||
@@ -439,7 +439,7 @@ void CreateDungeon(uint32_t rseed, lvl_entry entry)
|
||||
Make_SetPC(SetPiece);
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> LoadLevelSOLData()
|
||||
std::expected<void, std::string> LoadLevelSOLData()
|
||||
{
|
||||
switch (leveltype) {
|
||||
case DTYPE_TOWN:
|
||||
@@ -501,7 +501,7 @@ tl::expected<void, std::string> LoadLevelSOLData()
|
||||
SOLData[142] = TileProperties::None; // Tile is incorrectly marked as being solid
|
||||
break;
|
||||
default:
|
||||
return tl::make_unexpected("LoadLevelSOLData");
|
||||
return std::unexpected("LoadLevelSOLData");
|
||||
}
|
||||
return {};
|
||||
}
|
||||
@@ -833,7 +833,7 @@ void FloodTransparencyValues(uint8_t floorID)
|
||||
}
|
||||
}
|
||||
|
||||
tl::expected<dungeon_type, std::string> ParseDungeonType(std::string_view value)
|
||||
std::expected<dungeon_type, std::string> ParseDungeonType(std::string_view value)
|
||||
{
|
||||
if (value.empty()) return DTYPE_NONE;
|
||||
if (value == "DTYPE_TOWN") return DTYPE_TOWN;
|
||||
@@ -843,16 +843,16 @@ tl::expected<dungeon_type, std::string> ParseDungeonType(std::string_view value)
|
||||
if (value == "DTYPE_HELL") return DTYPE_HELL;
|
||||
if (value == "DTYPE_NEST") return DTYPE_NEST;
|
||||
if (value == "DTYPE_CRYPT") return DTYPE_CRYPT;
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
tl::expected<_setlevels, std::string> ParseSetLevel(std::string_view value)
|
||||
std::expected<_setlevels, std::string> ParseSetLevel(std::string_view value)
|
||||
{
|
||||
const std::optional<_setlevels> enumValueOpt = magic_enum::enum_cast<_setlevels>(value);
|
||||
if (enumValueOpt.has_value()) {
|
||||
return enumValueOpt.value();
|
||||
}
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
} // namespace devilution
|
||||
|
||||
@@ -7,13 +7,12 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "engine/clx_sprite.hpp"
|
||||
#include "engine/point.hpp"
|
||||
#include "engine/rectangle.hpp"
|
||||
@@ -58,8 +57,8 @@ inline bool IsArenaLevel(_setlevels setLevel)
|
||||
}
|
||||
}
|
||||
|
||||
tl::expected<dungeon_type, std::string> ParseDungeonType(std::string_view value);
|
||||
tl::expected<_setlevels, std::string> ParseSetLevel(std::string_view value);
|
||||
std::expected<dungeon_type, std::string> ParseDungeonType(std::string_view value);
|
||||
std::expected<_setlevels, std::string> ParseSetLevel(std::string_view value);
|
||||
|
||||
enum class DungeonFlag : uint8_t {
|
||||
// clang-format off
|
||||
@@ -298,7 +297,7 @@ struct Miniset {
|
||||
return HasAnyOf(SOLData[dPiece[coords.x][coords.y]], property);
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> LoadLevelSOLData();
|
||||
std::expected<void, std::string> LoadLevelSOLData();
|
||||
void SetDungeonMicros(std::unique_ptr<std::byte[]> &dungeonCels, uint_fast8_t µTileLen);
|
||||
void DRLG_InitTrans();
|
||||
void DRLG_MRectTrans(WorldTilePosition origin, WorldTilePosition extent);
|
||||
|
||||
+2
-3
@@ -8,11 +8,10 @@
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <expected>
|
||||
#include <numeric>
|
||||
#include <string>
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "automap.h"
|
||||
#include "engine/displacement.hpp"
|
||||
#include "engine/lighting_defs.hpp"
|
||||
@@ -221,7 +220,7 @@ void DoVision(Point position, uint8_t radius, MapExplorationType doAutomap, bool
|
||||
DoVision(position, radius, markVisibleFn, markTransparentFn, passesLightFn, inBoundsFn);
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> LoadTrns()
|
||||
std::expected<void, std::string> LoadTrns()
|
||||
{
|
||||
RETURN_IF_ERROR(LoadFileInMemWithStatus("plrgfx\\infra.trn", InfravisionTable));
|
||||
RETURN_IF_ERROR(LoadFileInMemWithStatus("plrgfx\\stone.trn", StoneTable));
|
||||
|
||||
+2
-3
@@ -7,8 +7,7 @@
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
#include <expected.hpp>
|
||||
#include <expected>
|
||||
|
||||
#include "automap.h"
|
||||
#include "engine/displacement.hpp"
|
||||
@@ -57,7 +56,7 @@ void DoUnLight(Point position, uint8_t radius);
|
||||
void DoLighting(Point position, uint8_t radius, DisplacementOf<int8_t> offset);
|
||||
void DoUnVision(Point position, uint8_t radius);
|
||||
void DoVision(Point position, uint8_t radius, MapExplorationType doAutomap, bool visible);
|
||||
tl::expected<void, std::string> LoadTrns();
|
||||
std::expected<void, std::string> LoadTrns();
|
||||
void MakeLightTable();
|
||||
#ifdef _DEBUG
|
||||
void ToggleLighting();
|
||||
|
||||
+9
-9
@@ -9,11 +9,11 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <expected>
|
||||
#include <numeric>
|
||||
#include <string>
|
||||
|
||||
#include <ankerl/unordered_dense.h>
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "automap.h"
|
||||
#include "codec.h"
|
||||
@@ -2004,7 +2004,7 @@ void SaveLevel(SaveWriter &saveWriter, LevelConversionData *levelConversionData)
|
||||
myPlayer._pSLvlVisited[setlvlnum] = true;
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> LoadLevel(LevelConversionData *levelConversionData)
|
||||
std::expected<void, std::string> LoadLevel(LevelConversionData *levelConversionData)
|
||||
{
|
||||
char szName[MaxMpqPathSize];
|
||||
std::optional<SaveReader> archive = OpenSaveArchive(gSaveNumber);
|
||||
@@ -2013,7 +2013,7 @@ tl::expected<void, std::string> LoadLevel(LevelConversionData *levelConversionDa
|
||||
GetPermLevelNames(szName);
|
||||
LoadHelper file(std::move(archive), szName);
|
||||
if (!file.IsValid())
|
||||
return tl::make_unexpected(std::string(_("Unable to open save file archive")));
|
||||
return std::unexpected(std::string(_("Unable to open save file archive")));
|
||||
|
||||
if (leveltype != DTYPE_TOWN) {
|
||||
for (int j = 0; j < MAXDUNY; j++) {
|
||||
@@ -2125,7 +2125,7 @@ bool IsStashSizeValid(size_t stashSize, uint32_t pages, uint32_t itemCount)
|
||||
|
||||
} // namespace
|
||||
|
||||
tl::expected<void, std::string> ConvertLevels(SaveWriter &saveWriter)
|
||||
std::expected<void, std::string> ConvertLevels(SaveWriter &saveWriter)
|
||||
{
|
||||
// Backup current level state
|
||||
const bool tmpSetlevel = setlevel;
|
||||
@@ -2464,17 +2464,17 @@ void RemoveEmptyInventory(Player &player)
|
||||
}
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> LoadGame(bool firstflag)
|
||||
std::expected<void, std::string> LoadGame(bool firstflag)
|
||||
{
|
||||
FreeGameMem();
|
||||
|
||||
LoadHelper file(OpenSaveArchive(gSaveNumber), "game");
|
||||
if (!file.IsValid()) {
|
||||
return tl::make_unexpected(std::string(_("Unable to open save file archive")));
|
||||
return std::unexpected(std::string(_("Unable to open save file archive")));
|
||||
}
|
||||
|
||||
if (!IsHeaderValid(file.NextLE<uint32_t>())) {
|
||||
return tl::make_unexpected(std::string(_("Invalid save file")));
|
||||
return std::unexpected(std::string(_("Invalid save file")));
|
||||
}
|
||||
|
||||
if (gbIsHellfireSaveGame) {
|
||||
@@ -2506,7 +2506,7 @@ tl::expected<void, std::string> LoadGame(bool firstflag)
|
||||
const int tmpNobjects = file.NextBE<int32_t>();
|
||||
|
||||
if (!gbIsHellfire && IsAnyOf(leveltype, DTYPE_NEST, DTYPE_CRYPT)) {
|
||||
return tl::make_unexpected(std::string(_("Player is on a Hellfire only level")));
|
||||
return std::unexpected(std::string(_("Player is on a Hellfire only level")));
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < giNumberOfLevels; i++) {
|
||||
@@ -2938,7 +2938,7 @@ void SaveLevel(SaveWriter &saveWriter)
|
||||
SaveLevel(saveWriter, nullptr);
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> LoadLevel()
|
||||
std::expected<void, std::string> LoadLevel()
|
||||
{
|
||||
return LoadLevel(nullptr);
|
||||
}
|
||||
|
||||
+4
-5
@@ -6,8 +6,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <expected.hpp>
|
||||
#include <expected>
|
||||
|
||||
#include "pfile.h"
|
||||
#include "player.h"
|
||||
@@ -36,14 +35,14 @@ void RemoveEmptyInventory(Player &player);
|
||||
* @brief Load game state
|
||||
* @param firstflag Can be set to false if we are simply reloading the current game
|
||||
*/
|
||||
tl::expected<void, std::string> LoadGame(bool firstflag);
|
||||
std::expected<void, std::string> LoadGame(bool firstflag);
|
||||
void SaveHotkeys(SaveWriter &saveWriter, const Player &player);
|
||||
void SaveHeroItems(SaveWriter &saveWriter, Player &player);
|
||||
void SaveGameData(SaveWriter &saveWriter);
|
||||
void SaveGame();
|
||||
void SaveLevel(SaveWriter &saveWriter);
|
||||
tl::expected<void, std::string> LoadLevel();
|
||||
tl::expected<void, std::string> ConvertLevels(SaveWriter &saveWriter);
|
||||
std::expected<void, std::string> LoadLevel();
|
||||
std::expected<void, std::string> ConvertLevels(SaveWriter &saveWriter);
|
||||
void LoadStash();
|
||||
void SaveStash(SaveWriter &stashWriter);
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ struct ValueInfo {
|
||||
|
||||
sol::protected_function LoadLuaFunctionSignatureGetter(sol::state &lua)
|
||||
{
|
||||
tl::expected<AssetData, std::string> src = LoadAsset("lua_internal\\get_lua_function_signature.lua");
|
||||
std::expected<AssetData, std::string> src = LoadAsset("lua_internal\\get_lua_function_signature.lua");
|
||||
if (!src.has_value()) {
|
||||
app_fatal(src.error());
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#include "lua/lua_global.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <expected>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include <ankerl/unordered_dense.h>
|
||||
#include <expected.hpp>
|
||||
#include <function_ref.hpp>
|
||||
#include <sol/bytecode.hpp>
|
||||
#include <sol/debug.hpp>
|
||||
@@ -113,7 +113,7 @@ sol::object LuaLoadScriptFromAssets(std::string_view packageName)
|
||||
return luaState.sol.load(iter->second.as_string_view(), path, sol::load_mode::binary);
|
||||
}
|
||||
|
||||
tl::expected<AssetData, std::string> assetData = LoadIntegralAsset(path);
|
||||
std::expected<AssetData, std::string> assetData = LoadIntegralAsset(path);
|
||||
if (!assetData.has_value()) {
|
||||
sol::stack::push(luaState.sol.lua_state(), assetData.error());
|
||||
return sol::stack_object(luaState.sol.lua_state(), -1);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <expected>
|
||||
#include <string_view>
|
||||
|
||||
#include <expected.hpp>
|
||||
#include <function_ref.hpp>
|
||||
#include <sol/forward.hpp>
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ std::string DebugCmdSpawnUniqueMonster(std::string name, std::optional<unsigned>
|
||||
if (!found) {
|
||||
if (LevelMonsterTypeCount == MaxLvlMTypes)
|
||||
LevelMonsterTypeCount--; // we are running out of monster types, so override last used monster type
|
||||
tl::expected<size_t, std::string> idResult = AddMonsterType(uniqueIndex, PLACE_SCATTER);
|
||||
std::expected<size_t, std::string> idResult = AddMonsterType(uniqueIndex, PLACE_SCATTER);
|
||||
if (!idResult.has_value()) return std::move(idResult).error();
|
||||
id = idResult.value();
|
||||
CMonster &monsterType = LevelMonsterTypes[id];
|
||||
@@ -134,7 +134,7 @@ std::string DebugCmdSpawnMonster(std::string name, std::optional<unsigned> count
|
||||
if (!found) {
|
||||
if (LevelMonsterTypeCount == MaxLvlMTypes)
|
||||
LevelMonsterTypeCount--; // we are running out of monster types, so override last used monster type
|
||||
tl::expected<size_t, std::string> idResult = AddMonsterType(static_cast<_monster_id>(mtype), PLACE_SCATTER);
|
||||
std::expected<size_t, std::string> idResult = AddMonsterType(static_cast<_monster_id>(mtype), PLACE_SCATTER);
|
||||
if (!idResult.has_value()) return std::move(idResult).error();
|
||||
id = idResult.value();
|
||||
CMonster &monsterType = LevelMonsterTypes[id];
|
||||
|
||||
+4
-4
@@ -2,11 +2,11 @@
|
||||
#include "lua/repl.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
#include <expected>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <expected.hpp>
|
||||
#include <sol/sol.hpp>
|
||||
#include <sol/utility/to_string.hpp>
|
||||
|
||||
@@ -87,14 +87,14 @@ sol::environment &GetLuaReplEnvironment()
|
||||
return *replEnv;
|
||||
}
|
||||
|
||||
tl::expected<std::string, std::string> RunLuaReplLine(std::string_view code)
|
||||
std::expected<std::string, std::string> RunLuaReplLine(std::string_view code)
|
||||
{
|
||||
const sol::protected_function_result result = TryRunLuaAsExpressionThenStatement(code);
|
||||
if (!result.valid()) {
|
||||
if (result.get_type() == sol::type::string) {
|
||||
return tl::make_unexpected(result.get<std::string>());
|
||||
return std::unexpected(result.get<std::string>());
|
||||
}
|
||||
return tl::make_unexpected("Unknown Lua error");
|
||||
return std::unexpected("Unknown Lua error");
|
||||
}
|
||||
if (result.get_type() == sol::type::none) {
|
||||
return std::string {};
|
||||
|
||||
+2
-2
@@ -1,15 +1,15 @@
|
||||
#pragma once
|
||||
#ifdef _DEBUG
|
||||
|
||||
#include <expected>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <expected.hpp>
|
||||
#include <sol/forward.hpp>
|
||||
|
||||
namespace devilution {
|
||||
|
||||
tl::expected<std::string, std::string> RunLuaReplLine(std::string_view code);
|
||||
std::expected<std::string, std::string> RunLuaReplLine(std::string_view code);
|
||||
|
||||
sol::environment &GetLuaReplEnvironment();
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <expected>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
@@ -95,7 +96,7 @@ bool HexToModHash(std::string_view hex, std::array<uint8_t, 32> &out)
|
||||
ModManifest ParseModManifest(std::string_view manifestIni)
|
||||
{
|
||||
ModManifest manifest;
|
||||
tl::expected<Ini, std::string> ini = Ini::parse(manifestIni);
|
||||
std::expected<Ini, std::string> ini = Ini::parse(manifestIni);
|
||||
if (!ini.has_value()) {
|
||||
LogError("Failed to parse mod manifest: {}", ini.error());
|
||||
return manifest;
|
||||
|
||||
+15
-15
@@ -14,6 +14,7 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <expected>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
@@ -30,7 +31,6 @@
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include <expected.hpp>
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
@@ -462,7 +462,7 @@ Point GetUniqueMonstPosition(UniqueMonsterType uniqindex)
|
||||
return position;
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> PlaceUniqueMonst(UniqueMonsterType uniqindex, size_t minionType, int bosspacksize)
|
||||
std::expected<void, std::string> PlaceUniqueMonst(UniqueMonsterType uniqindex, size_t minionType, int bosspacksize)
|
||||
{
|
||||
const auto &uniqueMonsterData = UniqueMonstersData[static_cast<size_t>(uniqindex)];
|
||||
const size_t typeIndex = GetMonsterTypeIndex(uniqueMonsterData.mtype);
|
||||
@@ -503,7 +503,7 @@ void ClrAllMonsters()
|
||||
}
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> PlaceUniqueMonsters()
|
||||
std::expected<void, std::string> PlaceUniqueMonsters()
|
||||
{
|
||||
for (size_t u = 0; u < UniqueMonstersData.size(); ++u) {
|
||||
if (UniqueMonstersData[u].mlevel != currlevel)
|
||||
@@ -530,7 +530,7 @@ tl::expected<void, std::string> PlaceUniqueMonsters()
|
||||
return {};
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> PlaceQuestMonsters()
|
||||
std::expected<void, std::string> PlaceQuestMonsters()
|
||||
{
|
||||
if (!setlevel) {
|
||||
if (Quests[Q_BUTCHER].IsAvailable()) {
|
||||
@@ -612,7 +612,7 @@ tl::expected<void, std::string> PlaceQuestMonsters()
|
||||
return {};
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> LoadDiabMonsts()
|
||||
std::expected<void, std::string> LoadDiabMonsts()
|
||||
{
|
||||
{
|
||||
ASSIGN_OR_RETURN(auto dunData, LoadFileInMemWithStatus<uint16_t>("levels\\l4data\\diab1.dun"));
|
||||
@@ -3288,7 +3288,7 @@ bool PosOkMovingMissile(Point position)
|
||||
|
||||
} // namespace
|
||||
|
||||
tl::expected<size_t, std::string> AddMonsterType(_monster_id type, placeflag placeflag)
|
||||
std::expected<size_t, std::string> AddMonsterType(_monster_id type, placeflag placeflag)
|
||||
{
|
||||
const size_t typeIndex = GetMonsterTypeIndex(type);
|
||||
CMonster &monsterType = LevelMonsterTypes[typeIndex];
|
||||
@@ -3316,7 +3316,7 @@ tl::expected<size_t, std::string> AddMonsterType(_monster_id type, placeflag pla
|
||||
return typeIndex;
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> InitTRNForUniqueMonster(Monster &monster)
|
||||
std::expected<void, std::string> InitTRNForUniqueMonster(Monster &monster)
|
||||
{
|
||||
char filestr[64];
|
||||
*BufCopy(filestr, R"(monsters\monsters\)", UniqueMonstersData[static_cast<size_t>(monster.uniqueType)].mTrnName, ".trn") = '\0';
|
||||
@@ -3324,7 +3324,7 @@ tl::expected<void, std::string> InitTRNForUniqueMonster(Monster &monster)
|
||||
return {};
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> PrepareUniqueMonst(Monster &monster, UniqueMonsterType monsterType, size_t minionType, int bosspacksize, const UniqueMonsterData &uniqueMonsterData)
|
||||
std::expected<void, std::string> PrepareUniqueMonst(Monster &monster, UniqueMonsterType monsterType, size_t minionType, int bosspacksize, const UniqueMonsterData &uniqueMonsterData)
|
||||
{
|
||||
monster.uniqueType = monsterType;
|
||||
monster.maxHitPoints = uniqueMonsterData.mmaxhp << 6;
|
||||
@@ -3431,7 +3431,7 @@ void InitLevelMonsters()
|
||||
uniquetrans = 0;
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> GetLevelMTypes()
|
||||
std::expected<void, std::string> GetLevelMTypes()
|
||||
{
|
||||
RETURN_IF_ERROR(AddMonsterType(MT_GOLEM, PLACE_SPECIAL));
|
||||
if (currlevel == 16) {
|
||||
@@ -3517,7 +3517,7 @@ tl::expected<void, std::string> GetLevelMTypes()
|
||||
return {};
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> InitMonsterSND(CMonster &monsterType)
|
||||
std::expected<void, std::string> InitMonsterSND(CMonster &monsterType)
|
||||
{
|
||||
if (!gbSndInited)
|
||||
return {};
|
||||
@@ -3546,7 +3546,7 @@ tl::expected<void, std::string> InitMonsterSND(CMonster &monsterType)
|
||||
return {};
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> InitMonsterGFX(CMonster &monsterType, MonsterSpritesData &&spritesData)
|
||||
std::expected<void, std::string> InitMonsterGFX(CMonster &monsterType, MonsterSpritesData &&spritesData)
|
||||
{
|
||||
if (HeadlessMode)
|
||||
return {};
|
||||
@@ -3620,7 +3620,7 @@ tl::expected<void, std::string> InitMonsterGFX(CMonster &monsterType, MonsterSpr
|
||||
return {};
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> InitAllMonsterGFX()
|
||||
std::expected<void, std::string> InitAllMonsterGFX()
|
||||
{
|
||||
if (HeadlessMode)
|
||||
return {};
|
||||
@@ -3685,7 +3685,7 @@ void InitGolems()
|
||||
}
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> InitMonsters()
|
||||
std::expected<void, std::string> InitMonsters()
|
||||
{
|
||||
if (!gbIsSpawn && !setlevel && currlevel == 16)
|
||||
LoadDiabMonsts();
|
||||
@@ -3748,7 +3748,7 @@ tl::expected<void, std::string> InitMonsters()
|
||||
return InitAllMonsterGFX();
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> SetMapMonsters(const uint16_t *dunData, Point startPosition)
|
||||
std::expected<void, std::string> SetMapMonsters(const uint16_t *dunData, Point startPosition)
|
||||
{
|
||||
RETURN_IF_ERROR(AddMonsterType(MT_GOLEM, PLACE_SPECIAL));
|
||||
if (setlevel)
|
||||
@@ -4392,7 +4392,7 @@ bool LineClearMovingMissile(Point startPoint, Point endPoint)
|
||||
return LineClear(PosOkMovingMissile, startPoint, endPoint);
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> SyncMonsterAnim(Monster &monster)
|
||||
std::expected<void, std::string> SyncMonsterAnim(Monster &monster)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
// fix for saves with debug monsters having type originally not on the level
|
||||
|
||||
+11
-11
@@ -7,12 +7,12 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
|
||||
#include <array>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
#include <expected.hpp>
|
||||
#include <function_ref.hpp>
|
||||
|
||||
#include "engine/actor_position.hpp"
|
||||
@@ -496,21 +496,21 @@ extern size_t ActiveMonsterCount;
|
||||
extern int MonsterKillCounts[NUM_MAX_MTYPES];
|
||||
extern bool sgbSaveSoundOn;
|
||||
|
||||
tl::expected<void, std::string> PrepareUniqueMonst(Monster &monster, UniqueMonsterType monsterType, size_t miniontype, int bosspacksize, const UniqueMonsterData &uniqueMonsterData);
|
||||
std::expected<void, std::string> PrepareUniqueMonst(Monster &monster, UniqueMonsterType monsterType, size_t miniontype, int bosspacksize, const UniqueMonsterData &uniqueMonsterData);
|
||||
void InitLevelMonsters();
|
||||
tl::expected<void, std::string> GetLevelMTypes();
|
||||
tl::expected<size_t, std::string> AddMonsterType(_monster_id type, placeflag placeflag);
|
||||
inline tl::expected<size_t, std::string> AddMonsterType(UniqueMonsterType uniqueType, placeflag placeflag)
|
||||
std::expected<void, std::string> GetLevelMTypes();
|
||||
std::expected<size_t, std::string> AddMonsterType(_monster_id type, placeflag placeflag);
|
||||
inline std::expected<size_t, std::string> AddMonsterType(UniqueMonsterType uniqueType, placeflag placeflag)
|
||||
{
|
||||
return AddMonsterType(UniqueMonstersData[static_cast<size_t>(uniqueType)].mtype, placeflag);
|
||||
}
|
||||
tl::expected<void, std::string> InitMonsterSND(CMonster &monsterType);
|
||||
tl::expected<void, std::string> InitMonsterGFX(CMonster &monsterType, MonsterSpritesData &&spritesData = {});
|
||||
tl::expected<void, std::string> InitAllMonsterGFX();
|
||||
std::expected<void, std::string> InitMonsterSND(CMonster &monsterType);
|
||||
std::expected<void, std::string> InitMonsterGFX(CMonster &monsterType, MonsterSpritesData &&spritesData = {});
|
||||
std::expected<void, std::string> InitAllMonsterGFX();
|
||||
void WeakenNaKrul();
|
||||
void InitGolems();
|
||||
tl::expected<void, std::string> InitMonsters();
|
||||
tl::expected<void, std::string> SetMapMonsters(const uint16_t *dunData, Point startPosition);
|
||||
std::expected<void, std::string> InitMonsters();
|
||||
std::expected<void, std::string> SetMapMonsters(const uint16_t *dunData, Point startPosition);
|
||||
Monster *AddMonster(Point position, Direction dir, size_t typeIndex, bool inMap);
|
||||
/**
|
||||
* @brief Spawns a new monsters (dynamically/not on level load).
|
||||
@@ -555,7 +555,7 @@ bool LineClearMissile(Point startPoint, Point endPoint);
|
||||
* @brief Checks for same missile obstructions as CheckMissileCol() for missiles that move along a path between two points
|
||||
*/
|
||||
bool LineClearMovingMissile(Point startPoint, Point endPoint);
|
||||
tl::expected<void, std::string> SyncMonsterAnim(Monster &monster);
|
||||
std::expected<void, std::string> SyncMonsterAnim(Monster &monster);
|
||||
void M_FallenFear(Point position);
|
||||
void PrintMonstHistory(int mt);
|
||||
void PrintUniqueHistory();
|
||||
|
||||
@@ -67,22 +67,22 @@ MpqArchive::~MpqArchive()
|
||||
mpqfs_close(archive_);
|
||||
}
|
||||
|
||||
tl::expected<MpqArchive, std::string> MpqArchive::Open(const char *path)
|
||||
std::expected<MpqArchive, std::string> MpqArchive::Open(const char *path)
|
||||
{
|
||||
mpqfs_archive_t *handle = nullptr;
|
||||
const mpqfs_error_code code = mpqfs_open(path, &handle);
|
||||
if (code != MPQFS_OK) {
|
||||
return tl::make_unexpected(FormatMpqfsError(code));
|
||||
return std::unexpected(FormatMpqfsError(code));
|
||||
}
|
||||
return MpqArchive(path, handle);
|
||||
}
|
||||
|
||||
tl::expected<MpqArchive, std::string> MpqArchive::Clone()
|
||||
std::expected<MpqArchive, std::string> MpqArchive::Clone()
|
||||
{
|
||||
mpqfs_archive_t *clone = nullptr;
|
||||
const mpqfs_error_code code = mpqfs_clone(archive_, &clone);
|
||||
if (code != MPQFS_OK) {
|
||||
return tl::make_unexpected(FormatMpqfsError(code));
|
||||
return std::unexpected(FormatMpqfsError(code));
|
||||
}
|
||||
return MpqArchive(path_, clone);
|
||||
}
|
||||
|
||||
@@ -2,12 +2,11 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
// Forward-declare so that we can avoid exposing mpqfs.h to all consumers.
|
||||
struct mpqfs_archive;
|
||||
typedef struct mpqfs_archive mpqfs_archive_t;
|
||||
@@ -16,8 +15,8 @@ namespace devilution {
|
||||
|
||||
class MpqArchive {
|
||||
public:
|
||||
static tl::expected<MpqArchive, std::string> Open(const char *path);
|
||||
tl::expected<MpqArchive, std::string> Clone();
|
||||
static std::expected<MpqArchive, std::string> Open(const char *path);
|
||||
std::expected<MpqArchive, std::string> Clone();
|
||||
|
||||
MpqArchive(MpqArchive &&other) noexcept;
|
||||
MpqArchive &operator=(MpqArchive &&other) noexcept;
|
||||
|
||||
+3
-3
@@ -7,11 +7,11 @@
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <ctime>
|
||||
#include <expected>
|
||||
#include <string>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <expected.hpp>
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
@@ -3681,7 +3681,7 @@ bool IsItemBlockingObjectAtPosition(Point position)
|
||||
return false;
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> LoadLevelObjects(uint16_t filesWidths[65])
|
||||
std::expected<void, std::string> LoadLevelObjects(uint16_t filesWidths[65])
|
||||
{
|
||||
if (HeadlessMode)
|
||||
return {};
|
||||
@@ -3706,7 +3706,7 @@ tl::expected<void, std::string> LoadLevelObjects(uint16_t filesWidths[65])
|
||||
return {};
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> InitObjectGFX()
|
||||
std::expected<void, std::string> InitObjectGFX()
|
||||
{
|
||||
uint16_t filesWidths[65] = {};
|
||||
|
||||
|
||||
+2
-3
@@ -7,10 +7,9 @@
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <string>
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "cursor.h"
|
||||
#include "engine/clx_sprite.hpp"
|
||||
#include "engine/point.hpp"
|
||||
@@ -329,7 +328,7 @@ inline Object &ObjectAtPosition(Point position)
|
||||
*/
|
||||
bool IsItemBlockingObjectAtPosition(Point position);
|
||||
|
||||
tl::expected<void, std::string> InitObjectGFX();
|
||||
std::expected<void, std::string> InitObjectGFX();
|
||||
void FreeObjectGFX();
|
||||
void AddL1Objs(int x1, int y1, int x2, int y2);
|
||||
void AddL2Objs(int x1, int y1, int x2, int y2);
|
||||
|
||||
+2
-2
@@ -10,6 +10,7 @@
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <expected>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <optional>
|
||||
@@ -26,7 +27,6 @@
|
||||
#include <SDL_version.h>
|
||||
#endif
|
||||
|
||||
#include <expected.hpp>
|
||||
#include <fmt/format.h>
|
||||
#include <function_ref.hpp>
|
||||
|
||||
@@ -157,7 +157,7 @@ void LoadIni()
|
||||
}
|
||||
std::fclose(file);
|
||||
}
|
||||
tl::expected<Ini, std::string> result = Ini::parse(std::string_view(buffer.data(), buffer.size()));
|
||||
std::expected<Ini, std::string> result = Ini::parse(std::string_view(buffer.data(), buffer.size()));
|
||||
if (!result.has_value()) app_fatal(result.error());
|
||||
ini.emplace(std::move(result).value());
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#include "panels/charpanel.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include <expected.hpp>
|
||||
#include <fmt/format.h>
|
||||
#include <function_ref.hpp>
|
||||
|
||||
@@ -270,7 +270,7 @@ void DrawStatButtons(const Surface &out)
|
||||
|
||||
} // namespace
|
||||
|
||||
tl::expected<void, std::string> LoadCharPanel()
|
||||
std::expected<void, std::string> LoadCharPanel()
|
||||
{
|
||||
ASSIGN_OR_RETURN(OptionalOwnedClxSpriteList background, LoadClxWithStatus("data\\charbg.clx"));
|
||||
const OwnedSurface out((*background)[0].width(), (*background)[0].height());
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <expected>
|
||||
#include <string>
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "engine/clx_sprite.hpp"
|
||||
#include "engine/surface.hpp"
|
||||
|
||||
@@ -12,7 +11,7 @@ namespace devilution {
|
||||
extern OptionalOwnedClxSpriteList pChrButtons;
|
||||
|
||||
void DrawChr(const Surface &);
|
||||
tl::expected<void, std::string> LoadCharPanel();
|
||||
std::expected<void, std::string> LoadCharPanel();
|
||||
void FreeCharPanel();
|
||||
|
||||
} // namespace devilution
|
||||
|
||||
@@ -53,7 +53,7 @@ constexpr std::string_view HelpText =
|
||||
" Up/Down to fill the input from history,"
|
||||
" Shift+Up/Down to fill the input from output history,"
|
||||
" Ctrl+L to clear history, Esc to close.";
|
||||
std::optional<tl::expected<AssetData, std::string>> ConsolePrelude;
|
||||
std::optional<std::expected<AssetData, std::string>> ConsolePrelude;
|
||||
|
||||
bool IsConsoleVisible;
|
||||
char ConsoleInputBuffer[4096];
|
||||
@@ -639,7 +639,7 @@ void InitConsole()
|
||||
void RunInConsole(std::string_view code)
|
||||
{
|
||||
AddConsoleLine(ConsoleLine { .type = ConsoleLine::Input, .text = StrCat(Prompt, code) });
|
||||
tl::expected<std::string, std::string> result = RunLuaReplLine(code);
|
||||
std::expected<std::string, std::string> result = RunLuaReplLine(code);
|
||||
|
||||
if (result.has_value()) {
|
||||
if (!result->empty()) {
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
#include "panels/mainpanel.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "control/control.hpp"
|
||||
#include "engine/clx_sprite.hpp"
|
||||
#include "engine/load_clx.hpp"
|
||||
@@ -70,7 +69,7 @@ void RenderMainButton(const Surface &out, int buttonId, std::string_view text, i
|
||||
|
||||
} // namespace
|
||||
|
||||
tl::expected<void, std::string> LoadMainPanel()
|
||||
std::expected<void, std::string> LoadMainPanel()
|
||||
{
|
||||
std::optional<OwnedSurface> out;
|
||||
constexpr uint16_t NumButtonSprites = 6;
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <expected>
|
||||
#include <string>
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "engine/clx_sprite.hpp"
|
||||
|
||||
namespace devilution {
|
||||
@@ -11,7 +10,7 @@ namespace devilution {
|
||||
extern OptionalOwnedClxSpriteList PanelButtonDown;
|
||||
extern OptionalOwnedClxSpriteList TalkButton;
|
||||
|
||||
tl::expected<void, std::string> LoadMainPanel();
|
||||
std::expected<void, std::string> LoadMainPanel();
|
||||
void FreeMainPanel();
|
||||
|
||||
} // namespace devilution
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "panels/partypanel.hpp"
|
||||
|
||||
#include <expected.hpp>
|
||||
#include <expected>
|
||||
#include <optional>
|
||||
|
||||
#include "automap.h"
|
||||
@@ -135,7 +135,7 @@ bool PartySidePanelOpen = true;
|
||||
bool InspectingFromPartyPanel;
|
||||
int PortraitIdUnderCursor = -1;
|
||||
|
||||
tl::expected<void, std::string> LoadPartyPanel()
|
||||
std::expected<void, std::string> LoadPartyPanel()
|
||||
{
|
||||
ASSIGN_OR_RETURN(OwnedClxSpriteList frame, LoadCelWithStatus("data\\textslid", FrameSpriteSize));
|
||||
ASSIGN_OR_RETURN(PlayerTags, LoadClxWithStatus("data\\monstertags.clx"));
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <expected>
|
||||
#include <string>
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "engine/clx_sprite.hpp"
|
||||
#include "engine/surface.hpp"
|
||||
|
||||
@@ -13,7 +12,7 @@ extern bool PartySidePanelOpen;
|
||||
extern bool InspectingFromPartyPanel;
|
||||
extern int PortraitIdUnderCursor;
|
||||
|
||||
tl::expected<void, std::string> LoadPartyPanel();
|
||||
std::expected<void, std::string> LoadPartyPanel();
|
||||
void FreePartyPanel();
|
||||
void DrawPartyMemberInfoPanel(const Surface &out);
|
||||
bool DidRightClickPartyPortrait();
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#include "panels/spell_book.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include <expected.hpp>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "control/control.hpp"
|
||||
@@ -119,7 +119,7 @@ StringOrView GetSpellPowerText(SpellID spell, int spellLevel)
|
||||
|
||||
} // namespace
|
||||
|
||||
tl::expected<void, std::string> InitSpellBook()
|
||||
std::expected<void, std::string> InitSpellBook()
|
||||
{
|
||||
ASSIGN_OR_RETURN(spellBookBackground, LoadCelWithStatus("data\\spellbk", static_cast<uint16_t>(SidePanelSize.width)));
|
||||
ASSIGN_OR_RETURN(spellBookButtons, LoadCelWithStatus("data\\spellbkb", SpellBookButtonWidth()));
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <expected>
|
||||
#include <string>
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "engine/clx_sprite.hpp"
|
||||
#include "engine/surface.hpp"
|
||||
|
||||
namespace devilution {
|
||||
|
||||
tl::expected<void, std::string> InitSpellBook();
|
||||
std::expected<void, std::string> InitSpellBook();
|
||||
void FreeSpellBook();
|
||||
void CheckSBook();
|
||||
void DrawSpellBook(const Surface &out);
|
||||
|
||||
@@ -84,7 +84,7 @@ const SpellIcon SpellITbl[] = {
|
||||
|
||||
} // namespace
|
||||
|
||||
tl::expected<void, std::string> LoadLargeSpellIcons()
|
||||
std::expected<void, std::string> LoadLargeSpellIcons()
|
||||
{
|
||||
#ifdef UNPACKED_MPQS
|
||||
LargeSpellIcons = LoadOptionalClx("data\\spelicon_fg.clx");
|
||||
@@ -111,7 +111,7 @@ void FreeLargeSpellIcons()
|
||||
LargeSpellIcons = std::nullopt;
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> LoadSmallSpellIcons()
|
||||
std::expected<void, std::string> LoadSmallSpellIcons()
|
||||
{
|
||||
#ifdef UNPACKED_MPQS
|
||||
ASSIGN_OR_RETURN(SmallSpellIcons, LoadClxWithStatus("data\\spelli2_fg.clx"));
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <string>
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "engine/clx_sprite.hpp"
|
||||
#include "engine/point.hpp"
|
||||
#include "engine/surface.hpp"
|
||||
@@ -109,10 +108,10 @@ void DrawSmallSpellIconBorder(const Surface &out, Point position);
|
||||
*/
|
||||
void SetSpellTrans(SpellType t);
|
||||
|
||||
tl::expected<void, std::string> LoadLargeSpellIcons();
|
||||
std::expected<void, std::string> LoadLargeSpellIcons();
|
||||
void FreeLargeSpellIcons();
|
||||
|
||||
tl::expected<void, std::string> LoadSmallSpellIcons();
|
||||
std::expected<void, std::string> LoadSmallSpellIcons();
|
||||
void FreeSmallSpellIcons();
|
||||
|
||||
} // namespace devilution
|
||||
|
||||
+3
-3
@@ -7,12 +7,12 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <ankerl/unordered_dense.h>
|
||||
#include <expected.hpp>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_iostream.h>
|
||||
@@ -265,7 +265,7 @@ std::optional<SaveReader> CreateSaveReader(std::string &&path)
|
||||
return std::nullopt;
|
||||
return SaveReader(std::move(path));
|
||||
#else
|
||||
tl::expected<MpqArchive, std::string> opened = MpqArchive::Open(path.c_str());
|
||||
std::expected<MpqArchive, std::string> opened = MpqArchive::Open(path.c_str());
|
||||
if (!opened.has_value()) return std::nullopt;
|
||||
return std::move(*opened);
|
||||
#endif
|
||||
@@ -809,7 +809,7 @@ void pfile_save_level()
|
||||
SaveLevel(saveWriter);
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> pfile_convert_levels()
|
||||
std::expected<void, std::string> pfile_convert_levels()
|
||||
{
|
||||
SaveWriter saveWriter = GetSaveWriter(gSaveNumber);
|
||||
return ConvertLevels(saveWriter);
|
||||
|
||||
+2
-3
@@ -6,10 +6,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <string>
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "DiabloUI/diabloui.h"
|
||||
#include "player.h"
|
||||
|
||||
@@ -125,7 +124,7 @@ bool pfile_ui_save_create(_uiheroinfo *heroinfo);
|
||||
bool pfile_delete_save(_uiheroinfo *heroInfo);
|
||||
void pfile_read_player_from_save(uint32_t saveNum, Player &player);
|
||||
void pfile_save_level();
|
||||
tl::expected<void, std::string> pfile_convert_levels();
|
||||
std::expected<void, std::string> pfile_convert_levels();
|
||||
void pfile_remove_temp_files();
|
||||
std::unique_ptr<std::byte[]> pfile_read(const char *pszName, size_t *pdwLen);
|
||||
void pfile_update(bool forceSave);
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace {
|
||||
|
||||
bool AreExtraFontsOutOfDateForMpqPath(const char *mpqPath)
|
||||
{
|
||||
tl::expected<MpqArchive, std::string> archive = MpqArchive::Open(mpqPath);
|
||||
std::expected<MpqArchive, std::string> archive = MpqArchive::Open(mpqPath);
|
||||
return archive.has_value() && AreExtraFontsOutOfDate(*archive);
|
||||
}
|
||||
|
||||
|
||||
+25
-25
@@ -41,18 +41,18 @@ std::vector<PLStruct> ItemPrefixes;
|
||||
/** Contains the data related to each item suffix. */
|
||||
std::vector<PLStruct> ItemSuffixes;
|
||||
|
||||
tl::expected<_item_indexes, std::string> ParseItemId(std::string_view value)
|
||||
std::expected<_item_indexes, std::string> ParseItemId(std::string_view value)
|
||||
{
|
||||
const std::optional<_item_indexes> enumValueOpt = magic_enum::enum_cast<_item_indexes>(value);
|
||||
if (enumValueOpt.has_value()) {
|
||||
return enumValueOpt.value();
|
||||
}
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
tl::expected<item_class, std::string> ParseItemClass(std::string_view value)
|
||||
std::expected<item_class, std::string> ParseItemClass(std::string_view value)
|
||||
{
|
||||
if (value == "None") return ICLASS_NONE;
|
||||
if (value == "Weapon") return ICLASS_WEAPON;
|
||||
@@ -60,10 +60,10 @@ tl::expected<item_class, std::string> ParseItemClass(std::string_view value)
|
||||
if (value == "Misc") return ICLASS_MISC;
|
||||
if (value == "Gold") return ICLASS_GOLD;
|
||||
if (value == "Quest") return ICLASS_QUEST;
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
tl::expected<item_equip_type, std::string> ParseItemEquipType(std::string_view value)
|
||||
std::expected<item_equip_type, std::string> ParseItemEquipType(std::string_view value)
|
||||
{
|
||||
if (value == "None") return ILOC_NONE;
|
||||
if (value == "One-handed") return ILOC_ONEHAND;
|
||||
@@ -74,10 +74,10 @@ tl::expected<item_equip_type, std::string> ParseItemEquipType(std::string_view v
|
||||
if (value == "Amulet") return ILOC_AMULET;
|
||||
if (value == "Unequippable") return ILOC_UNEQUIPABLE;
|
||||
if (value == "Belt") return ILOC_BELT;
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
tl::expected<item_cursor_graphic, std::string> ParseItemCursorGraphic(std::string_view value)
|
||||
std::expected<item_cursor_graphic, std::string> ParseItemCursorGraphic(std::string_view value)
|
||||
{
|
||||
if (value == "POTION_OF_FULL_MANA") return ICURS_POTION_OF_FULL_MANA;
|
||||
if (value == "SCROLL_OF") return ICURS_SCROLL_OF;
|
||||
@@ -253,11 +253,11 @@ tl::expected<item_cursor_graphic, std::string> ParseItemCursorGraphic(std::strin
|
||||
|
||||
// also support providing the item cursor icon frame number directly
|
||||
return ParseInt<uint8_t>(value)
|
||||
.map([](auto numericalValue) { return static_cast<item_cursor_graphic>(numericalValue); })
|
||||
.map_error([](auto) { return std::string("Unknown enum value"); });
|
||||
.transform([](auto numericalValue) { return static_cast<item_cursor_graphic>(numericalValue); })
|
||||
.transform_error([](auto) { return std::string("Unknown enum value"); });
|
||||
}
|
||||
|
||||
tl::expected<ItemType, std::string> ParseItemType(std::string_view value)
|
||||
std::expected<ItemType, std::string> ParseItemType(std::string_view value)
|
||||
{
|
||||
if (value == "Misc") return ItemType::Misc;
|
||||
if (value == "Sword") return ItemType::Sword;
|
||||
@@ -274,10 +274,10 @@ tl::expected<ItemType, std::string> ParseItemType(std::string_view value)
|
||||
if (value == "Ring") return ItemType::Ring;
|
||||
if (value == "Amulet") return ItemType::Amulet;
|
||||
if (value == "None") return ItemType::None;
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
tl::expected<unique_base_item, std::string> ParseUniqueBaseItem(std::string_view value)
|
||||
std::expected<unique_base_item, std::string> ParseUniqueBaseItem(std::string_view value)
|
||||
{
|
||||
if (value == "NONE") return UITYPE_NONE;
|
||||
if (value == "SHORTBOW") return UITYPE_SHORTBOW;
|
||||
@@ -354,10 +354,10 @@ tl::expected<unique_base_item, std::string> ParseUniqueBaseItem(std::string_view
|
||||
return static_cast<unique_base_item>(findIt->second);
|
||||
}
|
||||
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
tl::expected<unique_base_item, std::string> ParseOrAddUniqueBaseItem(std::string_view value)
|
||||
std::expected<unique_base_item, std::string> ParseOrAddUniqueBaseItem(std::string_view value)
|
||||
{
|
||||
const auto parseResult = ParseUniqueBaseItem(value);
|
||||
if (parseResult.has_value()) {
|
||||
@@ -367,7 +367,7 @@ tl::expected<unique_base_item, std::string> ParseOrAddUniqueBaseItem(std::string
|
||||
const size_t newUniqueBaseItemIndex = static_cast<size_t>(NUM_DEFAULT_UITYPES) + AdditionalUniqueBaseItemStringsToIndices.size();
|
||||
|
||||
if (newUniqueBaseItemIndex >= static_cast<size_t>(NUM_MAX_UITYPES)) {
|
||||
return tl::make_unexpected(fmt::format("Could not define new unique base item \"{}\", since the maximum number of {} has already been reached.", value, static_cast<size_t>(NUM_MAX_UITYPES)));
|
||||
return std::unexpected(fmt::format("Could not define new unique base item \"{}\", since the maximum number of {} has already been reached.", value, static_cast<size_t>(NUM_MAX_UITYPES)));
|
||||
}
|
||||
|
||||
const auto newUniqueBaseItem = static_cast<unique_base_item>(newUniqueBaseItemIndex);
|
||||
@@ -375,7 +375,7 @@ tl::expected<unique_base_item, std::string> ParseOrAddUniqueBaseItem(std::string
|
||||
return newUniqueBaseItem;
|
||||
}
|
||||
|
||||
tl::expected<ItemSpecialEffect, std::string> ParseItemSpecialEffect(std::string_view value)
|
||||
std::expected<ItemSpecialEffect, std::string> ParseItemSpecialEffect(std::string_view value)
|
||||
{
|
||||
if (value == "RandomStealLife") return ItemSpecialEffect::RandomStealLife;
|
||||
if (value == "RandomArrowVelocity") return ItemSpecialEffect::RandomArrowVelocity;
|
||||
@@ -403,10 +403,10 @@ tl::expected<ItemSpecialEffect, std::string> ParseItemSpecialEffect(std::string_
|
||||
if (value == "HalfTrapDamage") return ItemSpecialEffect::HalfTrapDamage;
|
||||
if (value == "TripleDemonDamage") return ItemSpecialEffect::TripleDemonDamage;
|
||||
if (value == "ZeroResistance") return ItemSpecialEffect::ZeroResistance;
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
tl::expected<item_misc_id, std::string> ParseItemMiscId(std::string_view value)
|
||||
std::expected<item_misc_id, std::string> ParseItemMiscId(std::string_view value)
|
||||
{
|
||||
if (value == "NONE") return IMISC_NONE;
|
||||
if (value == "USEFIRST") return IMISC_USEFIRST;
|
||||
@@ -454,10 +454,10 @@ tl::expected<item_misc_id, std::string> ParseItemMiscId(std::string_view value)
|
||||
if (value == "AURIC") return IMISC_AURIC;
|
||||
if (value == "NOTE") return IMISC_NOTE;
|
||||
if (value == "ARENAPOT") return IMISC_ARENAPOT;
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
tl::expected<item_effect_type, std::string> ParseItemEffectType(std::string_view value)
|
||||
std::expected<item_effect_type, std::string> ParseItemEffectType(std::string_view value)
|
||||
{
|
||||
if (value == "TOHIT") return IPL_TOHIT;
|
||||
if (value == "TOHIT_CURSE") return IPL_TOHIT_CURSE;
|
||||
@@ -539,10 +539,10 @@ tl::expected<item_effect_type, std::string> ParseItemEffectType(std::string_view
|
||||
if (value == "ACUNDEAD") return IPL_ACUNDEAD;
|
||||
if (value == "MANATOLIFE") return IPL_MANATOLIFE;
|
||||
if (value == "LIFETOMANA") return IPL_LIFETOMANA;
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
tl::expected<AffixItemType, std::string> ParseAffixItemType(std::string_view value)
|
||||
std::expected<AffixItemType, std::string> ParseAffixItemType(std::string_view value)
|
||||
{
|
||||
if (value == "Misc") return AffixItemType::Misc;
|
||||
if (value == "Bow") return AffixItemType::Bow;
|
||||
@@ -550,15 +550,15 @@ tl::expected<AffixItemType, std::string> ParseAffixItemType(std::string_view val
|
||||
if (value == "Weapon") return AffixItemType::Weapon;
|
||||
if (value == "Shield") return AffixItemType::Shield;
|
||||
if (value == "Armor") return AffixItemType::Armor;
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
tl::expected<goodorevil, std::string> ParseAffixAlignment(std::string_view value)
|
||||
std::expected<goodorevil, std::string> ParseAffixAlignment(std::string_view value)
|
||||
{
|
||||
if (value == "Any") return GOE_ANY;
|
||||
if (value == "Evil") return GOE_EVIL;
|
||||
if (value == "Good") return GOE_GOOD;
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include <ankerl/unordered_dense.h>
|
||||
#include <expected.hpp>
|
||||
#include <magic_enum/magic_enum.hpp>
|
||||
|
||||
#include "tables/objdat.h"
|
||||
@@ -656,7 +656,7 @@ extern std::vector<PLStruct> ItemSuffixes;
|
||||
extern DVL_API_FOR_TEST std::vector<UniqueItem> UniqueItems;
|
||||
extern ankerl::unordered_dense::map<int32_t, int32_t> UniqueItemMappingIdsToIndices;
|
||||
|
||||
tl::expected<_item_indexes, std::string> ParseItemId(std::string_view value);
|
||||
std::expected<_item_indexes, std::string> ParseItemId(std::string_view value);
|
||||
void LoadItemDatFromFile(DataFile &dataFile, std::string_view filename, int32_t baseMappingId);
|
||||
void LoadUniqueItemDatFromFile(DataFile &dataFile, std::string_view filename, int32_t baseMappingId);
|
||||
void LoadItemData();
|
||||
|
||||
+19
-20
@@ -9,14 +9,13 @@
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "data/file.hpp"
|
||||
#include "data/iterators.hpp"
|
||||
#include "data/record_reader.hpp"
|
||||
@@ -57,15 +56,15 @@ size_t ToIndex(std::vector<std::array<uint8_t, 16>> &all, const std::array<uint8
|
||||
return all.size() - 1;
|
||||
}
|
||||
|
||||
tl::expected<MissileGraphicsFlags, std::string> ParseMissileGraphicsFlag(std::string_view value)
|
||||
std::expected<MissileGraphicsFlags, std::string> ParseMissileGraphicsFlag(std::string_view value)
|
||||
{
|
||||
if (value.empty()) return MissileGraphicsFlags::None;
|
||||
if (value == "MonsterOwned") return MissileGraphicsFlags::MonsterOwned;
|
||||
if (value == "NotAnimated") return MissileGraphicsFlags::NotAnimated;
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
tl::expected<MissileGraphicID, std::string> ParseMissileGraphicID(std::string_view value)
|
||||
std::expected<MissileGraphicID, std::string> ParseMissileGraphicID(std::string_view value)
|
||||
{
|
||||
if (value.empty()) return MissileGraphicID::None;
|
||||
if (value == "Arrow") return MissileGraphicID::Arrow;
|
||||
@@ -127,7 +126,7 @@ tl::expected<MissileGraphicID, std::string> ParseMissileGraphicID(std::string_vi
|
||||
if (value == "BlueFlare2") return MissileGraphicID::BlueFlare2;
|
||||
if (value == "OrangeFlareExplosion") return MissileGraphicID::OrangeFlareExplosion;
|
||||
if (value == "BlueFlareExplosion2") return MissileGraphicID::BlueFlareExplosion2;
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
void LoadMissileSpriteData()
|
||||
@@ -166,7 +165,7 @@ void LoadMissileSpriteData()
|
||||
MissileAnimLengths.shrink_to_fit();
|
||||
}
|
||||
|
||||
tl::expected<MissileDataFlags, std::string> ParseMissileDataFlag(std::string_view value)
|
||||
std::expected<MissileDataFlags, std::string> ParseMissileDataFlag(std::string_view value)
|
||||
{
|
||||
if (value == "Physical") return MissileDataFlags::Physical;
|
||||
if (value == "Fire") return MissileDataFlags::Fire;
|
||||
@@ -175,11 +174,11 @@ tl::expected<MissileDataFlags, std::string> ParseMissileDataFlag(std::string_vie
|
||||
if (value == "Acid") return MissileDataFlags::Acid;
|
||||
if (value == "Arrow") return MissileDataFlags::Arrow;
|
||||
if (value == "Invisible") return MissileDataFlags::Invisible;
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
|
||||
tl::expected<MissileData::AddFn, std::string> ParseMissileAddFn(std::string_view value)
|
||||
std::expected<MissileData::AddFn, std::string> ParseMissileAddFn(std::string_view value)
|
||||
{
|
||||
if (value.empty()) return nullptr;
|
||||
if (value == "AddOpenNest") return AddOpenNest;
|
||||
@@ -255,11 +254,11 @@ tl::expected<MissileData::AddFn, std::string> ParseMissileAddFn(std::string_view
|
||||
if (value == "AddBoneSpirit") return AddBoneSpirit;
|
||||
if (value == "AddRedPortal") return AddRedPortal;
|
||||
if (value == "AddDiabloApocalypse") return AddDiabloApocalypse;
|
||||
return tl::make_unexpected("Unknown MissileData::AddFn name");
|
||||
return std::unexpected("Unknown MissileData::AddFn name");
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
|
||||
tl::expected<MissileData::ProcessFn, std::string> ParseMissileProcessFn(std::string_view value)
|
||||
std::expected<MissileData::ProcessFn, std::string> ParseMissileProcessFn(std::string_view value)
|
||||
{
|
||||
if (value.empty()) return nullptr;
|
||||
if (value == "ProcessElementalArrow") return ProcessElementalArrow;
|
||||
@@ -307,12 +306,12 @@ tl::expected<MissileData::ProcessFn, std::string> ParseMissileProcessFn(std::str
|
||||
if (value == "ProcessBoneSpirit") return ProcessBoneSpirit;
|
||||
if (value == "ProcessResurrectBeam") return ProcessResurrectBeam;
|
||||
if (value == "ProcessRedPortal") return ProcessRedPortal;
|
||||
return tl::make_unexpected("Unknown MissileData::ProcessFn name");
|
||||
return std::unexpected("Unknown MissileData::ProcessFn name");
|
||||
}
|
||||
|
||||
// A temporary solution for parsing SfxID until we have a more general one.
|
||||
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
|
||||
tl::expected<SfxID, std::string> ParseCastSound(std::string_view value)
|
||||
std::expected<SfxID, std::string> ParseCastSound(std::string_view value)
|
||||
{
|
||||
if (value.empty()) return SfxID::None;
|
||||
if (value == "BigExplosion") return SfxID::BigExplosion;
|
||||
@@ -345,11 +344,11 @@ tl::expected<SfxID, std::string> ParseCastSound(std::string_view value)
|
||||
if (value == "SpellStoneCurse") return SfxID::SpellStoneCurse;
|
||||
if (value == "SpellTeleport") return SfxID::SpellTeleport;
|
||||
if (value == "SpellTrapDisarm") return SfxID::SpellTrapDisarm;
|
||||
return tl::make_unexpected("Unknown enum value (only a few are supported for now)");
|
||||
return std::unexpected("Unknown enum value (only a few are supported for now)");
|
||||
}
|
||||
|
||||
// A temporary solution for parsing SfxID until we have a more general one.
|
||||
tl::expected<SfxID, std::string> ParseHitSound(std::string_view value)
|
||||
std::expected<SfxID, std::string> ParseHitSound(std::string_view value)
|
||||
{
|
||||
if (value.empty()) return SfxID::None;
|
||||
if (value == "BigExplosion") return SfxID::BigExplosion;
|
||||
@@ -358,15 +357,15 @@ tl::expected<SfxID, std::string> ParseHitSound(std::string_view value)
|
||||
if (value == "SpellFireHit") return SfxID::SpellFireHit;
|
||||
if (value == "SpellLightningHit") return SfxID::SpellLightningHit;
|
||||
if (value == "SpellResurrect") return SfxID::SpellResurrect;
|
||||
return tl::make_unexpected("Unknown enum value (only a few are supported for now)");
|
||||
return std::unexpected("Unknown enum value (only a few are supported for now)");
|
||||
}
|
||||
|
||||
tl::expected<MissileMovementDistribution, std::string> ParseMissileMovementDistribution(std::string_view value)
|
||||
std::expected<MissileMovementDistribution, std::string> ParseMissileMovementDistribution(std::string_view value)
|
||||
{
|
||||
if (value.empty()) return MissileMovementDistribution::Disabled;
|
||||
if (value == "Blockable") return MissileMovementDistribution::Blockable;
|
||||
if (value == "Unblockable") return MissileMovementDistribution::Unblockable;
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
void LoadMisdat()
|
||||
@@ -408,7 +407,7 @@ uint8_t MissileFileData::animLen(uint8_t dir) const
|
||||
return MissileAnimLengths[animLenIdx][dir];
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> MissileFileData::LoadGFX()
|
||||
std::expected<void, std::string> MissileFileData::LoadGFX()
|
||||
{
|
||||
if (sprites)
|
||||
return {};
|
||||
@@ -451,7 +450,7 @@ const MissileData &GetMissileData(MissileID missileId)
|
||||
return MissilesData[static_cast<std::underlying_type_t<MissileID>>(missileId)];
|
||||
}
|
||||
|
||||
tl::expected<void, std::string> InitMissileGFX()
|
||||
std::expected<void, std::string> InitMissileGFX()
|
||||
{
|
||||
if (HeadlessMode)
|
||||
return {};
|
||||
|
||||
@@ -7,11 +7,10 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "effects.h"
|
||||
#include "engine/clx_sprite.hpp"
|
||||
#include "tables/spelldat.h"
|
||||
@@ -220,7 +219,7 @@ struct MissileFileData {
|
||||
[[nodiscard]] uint8_t animDelay(uint8_t dir) const;
|
||||
[[nodiscard]] uint8_t animLen(uint8_t dir) const;
|
||||
|
||||
tl::expected<void, std::string> LoadGFX();
|
||||
std::expected<void, std::string> LoadGFX();
|
||||
|
||||
void FreeGFX()
|
||||
{
|
||||
@@ -246,7 +245,7 @@ MissileFileData &GetMissileSpriteData(MissileGraphicID graphicId);
|
||||
|
||||
void LoadMissileData();
|
||||
|
||||
tl::expected<void, std::string> InitMissileGFX();
|
||||
std::expected<void, std::string> InitMissileGFX();
|
||||
void FreeMissileGFX();
|
||||
|
||||
} // namespace devilution
|
||||
|
||||
+19
-19
@@ -8,13 +8,13 @@
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include <ankerl/unordered_dense.h>
|
||||
#include <expected.hpp>
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
#include <magic_enum/magic_enum.hpp>
|
||||
@@ -223,7 +223,7 @@ namespace {
|
||||
/** Contains the mapping between monster ID strings and indices, used for parsing additional monster data. */
|
||||
ankerl::unordered_dense::map<std::string, int16_t> AdditionalMonsterIdStringsToIndices;
|
||||
|
||||
tl::expected<_monster_id, std::string> ParseMonsterId(std::string_view value)
|
||||
std::expected<_monster_id, std::string> ParseMonsterId(std::string_view value)
|
||||
{
|
||||
const std::optional<_monster_id> enumValueOpt = magic_enum::enum_cast<_monster_id>(value);
|
||||
if (enumValueOpt.has_value()) {
|
||||
@@ -233,27 +233,27 @@ tl::expected<_monster_id, std::string> ParseMonsterId(std::string_view value)
|
||||
if (findIt != AdditionalMonsterIdStringsToIndices.end()) {
|
||||
return static_cast<_monster_id>(findIt->second);
|
||||
}
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
tl::expected<MonsterAvailability, std::string> ParseMonsterAvailability(std::string_view value)
|
||||
std::expected<MonsterAvailability, std::string> ParseMonsterAvailability(std::string_view value)
|
||||
{
|
||||
if (value == "Always") return MonsterAvailability::Always;
|
||||
if (value == "Never") return MonsterAvailability::Never;
|
||||
if (value == "Retail") return MonsterAvailability::Retail;
|
||||
return tl::make_unexpected("Expected one of: Always, Never, or Retail");
|
||||
return std::unexpected("Expected one of: Always, Never, or Retail");
|
||||
}
|
||||
|
||||
tl::expected<MonsterAIID, std::string> ParseAiId(std::string_view value)
|
||||
std::expected<MonsterAIID, std::string> ParseAiId(std::string_view value)
|
||||
{
|
||||
const std::optional<MonsterAIID> enumValueOpt = magic_enum::enum_cast<MonsterAIID>(value);
|
||||
if (enumValueOpt.has_value()) {
|
||||
return enumValueOpt.value();
|
||||
}
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
tl::expected<monster_flag, std::string> ParseMonsterFlag(std::string_view value)
|
||||
std::expected<monster_flag, std::string> ParseMonsterFlag(std::string_view value)
|
||||
{
|
||||
if (value == "HIDDEN") return MFLAG_HIDDEN;
|
||||
if (value == "LOCK_ANIMATION") return MFLAG_LOCK_ANIMATION;
|
||||
@@ -267,37 +267,37 @@ tl::expected<monster_flag, std::string> ParseMonsterFlag(std::string_view value)
|
||||
if (value == "NO_ENEMY") return MFLAG_NO_ENEMY;
|
||||
if (value == "BERSERK") return MFLAG_BERSERK;
|
||||
if (value == "NOLIFESTEAL") return MFLAG_NOLIFESTEAL;
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
tl::expected<MonsterClass, std::string> ParseMonsterClass(std::string_view value)
|
||||
std::expected<MonsterClass, std::string> ParseMonsterClass(std::string_view value)
|
||||
{
|
||||
const std::optional<MonsterClass> enumValueOpt = magic_enum::enum_cast<MonsterClass>(value);
|
||||
if (enumValueOpt.has_value()) {
|
||||
return enumValueOpt.value();
|
||||
}
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
tl::expected<monster_resistance, std::string> ParseMonsterResistance(std::string_view value)
|
||||
std::expected<monster_resistance, std::string> ParseMonsterResistance(std::string_view value)
|
||||
{
|
||||
const std::optional<monster_resistance> enumValueOpt = magic_enum::enum_cast<monster_resistance>(value);
|
||||
if (enumValueOpt.has_value()) {
|
||||
return enumValueOpt.value();
|
||||
}
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
tl::expected<SelectionRegion, std::string> ParseSelectionRegion(std::string_view value)
|
||||
std::expected<SelectionRegion, std::string> ParseSelectionRegion(std::string_view value)
|
||||
{
|
||||
if (value.empty()) return SelectionRegion::None;
|
||||
if (value == "Bottom") return SelectionRegion::Bottom;
|
||||
if (value == "Middle") return SelectionRegion::Middle;
|
||||
if (value == "Top") return SelectionRegion::Top;
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
tl::expected<uint16_t, std::string> ParseMonsterTreasure(std::string_view value)
|
||||
std::expected<uint16_t, std::string> ParseMonsterTreasure(std::string_view value)
|
||||
{
|
||||
// TODO: Replace this hack with proper parsing.
|
||||
|
||||
@@ -305,16 +305,16 @@ tl::expected<uint16_t, std::string> ParseMonsterTreasure(std::string_view value)
|
||||
if (value == "None") return T_NODROP;
|
||||
if (value == "Uniq(SKCROWN)") return Uniq(UITEM_SKCROWN);
|
||||
if (value == "Uniq(CLEAVER)") return Uniq(UITEM_CLEAVER);
|
||||
return tl::make_unexpected("Invalid value. NOTE: Parser is incomplete");
|
||||
return std::unexpected("Invalid value. NOTE: Parser is incomplete");
|
||||
}
|
||||
|
||||
tl::expected<UniqueMonsterPack, std::string> ParseUniqueMonsterPack(std::string_view value)
|
||||
std::expected<UniqueMonsterPack, std::string> ParseUniqueMonsterPack(std::string_view value)
|
||||
{
|
||||
const std::optional<UniqueMonsterPack> enumValueOpt = magic_enum::enum_cast<UniqueMonsterPack>(value);
|
||||
if (enumValueOpt.has_value()) {
|
||||
return enumValueOpt.value();
|
||||
}
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
*/
|
||||
#include "tables/objdat.h"
|
||||
|
||||
#include <expected>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include <ankerl/unordered_dense.h>
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "cursor.h"
|
||||
#include "data/file.hpp"
|
||||
@@ -178,7 +178,7 @@ std::vector<std::string> ObjMasterLoadList;
|
||||
|
||||
namespace {
|
||||
|
||||
tl::expected<theme_id, std::string> ParseTheme(std::string_view value)
|
||||
std::expected<theme_id, std::string> ParseTheme(std::string_view value)
|
||||
{
|
||||
if (value.empty()) return THEME_NONE;
|
||||
if (value == "THEME_BARREL") return THEME_BARREL;
|
||||
@@ -198,10 +198,10 @@ tl::expected<theme_id, std::string> ParseTheme(std::string_view value)
|
||||
if (value == "THEME_TEARFOUNTAIN") return THEME_TEARFOUNTAIN;
|
||||
if (value == "THEME_BRNCROSS") return THEME_BRNCROSS;
|
||||
if (value == "THEME_WEAPONRACK") return THEME_WEAPONRACK;
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
tl::expected<quest_id, std::string> ParseQuest(std::string_view value)
|
||||
std::expected<quest_id, std::string> ParseQuest(std::string_view value)
|
||||
{
|
||||
if (value.empty()) return Q_INVALID;
|
||||
if (value == "Q_ROCK") return Q_ROCK;
|
||||
@@ -228,10 +228,10 @@ tl::expected<quest_id, std::string> ParseQuest(std::string_view value)
|
||||
if (value == "Q_NAKRUL") return Q_NAKRUL;
|
||||
if (value == "Q_CORNSTN") return Q_CORNSTN;
|
||||
if (value == "Q_JERSEY") return Q_JERSEY;
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
tl::expected<ObjectDataFlags, std::string> ParseObjectDataFlags(std::string_view value)
|
||||
std::expected<ObjectDataFlags, std::string> ParseObjectDataFlags(std::string_view value)
|
||||
{
|
||||
if (value.empty()) return ObjectDataFlags::None;
|
||||
if (value == "Animated") return ObjectDataFlags::Animated;
|
||||
@@ -240,16 +240,16 @@ tl::expected<ObjectDataFlags, std::string> ParseObjectDataFlags(std::string_view
|
||||
if (value == "Light") return ObjectDataFlags::Light;
|
||||
if (value == "Trap") return ObjectDataFlags::Trap;
|
||||
if (value == "Breakable") return ObjectDataFlags::Breakable;
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
tl::expected<SelectionRegion, std::string> ParseSelectionRegion(std::string_view value)
|
||||
std::expected<SelectionRegion, std::string> ParseSelectionRegion(std::string_view value)
|
||||
{
|
||||
if (value.empty()) return SelectionRegion::None;
|
||||
if (value == "Bottom") return SelectionRegion::Bottom;
|
||||
if (value == "Middle") return SelectionRegion::Middle;
|
||||
if (value == "Top") return SelectionRegion::Top;
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
+10
-10
@@ -11,9 +11,9 @@
|
||||
#include <bitset>
|
||||
#include <charconv>
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <vector>
|
||||
|
||||
#include <expected.hpp>
|
||||
#include <fmt/format.h>
|
||||
#include <magic_enum/magic_enum_utility.hpp>
|
||||
|
||||
@@ -74,7 +74,7 @@ enum class ExperienceColumn {
|
||||
LAST = Experience
|
||||
};
|
||||
|
||||
tl::expected<ExperienceColumn, ColumnDefinition::Error> mapExperienceColumnFromName(std::string_view name)
|
||||
std::expected<ExperienceColumn, ColumnDefinition::Error> mapExperienceColumnFromName(std::string_view name)
|
||||
{
|
||||
if (name == "Level") {
|
||||
return ExperienceColumn::Level;
|
||||
@@ -82,7 +82,7 @@ tl::expected<ExperienceColumn, ColumnDefinition::Error> mapExperienceColumnFromN
|
||||
if (name == "Experience") {
|
||||
return ExperienceColumn::Experience;
|
||||
}
|
||||
return tl::unexpected { ColumnDefinition::Error::UnknownColumn };
|
||||
return std::unexpected { ColumnDefinition::Error::UnknownColumn };
|
||||
}
|
||||
|
||||
void ReloadExperienceData()
|
||||
@@ -156,19 +156,19 @@ void ReloadExperienceData()
|
||||
}
|
||||
}
|
||||
|
||||
tl::expected<PlayerClassFlag, std::string> ParsePlayerClassFlag(std::string_view value)
|
||||
std::expected<PlayerClassFlag, std::string> ParsePlayerClassFlag(std::string_view value)
|
||||
{
|
||||
const std::optional<PlayerClassFlag> enumValueOpt = magic_enum::enum_cast<PlayerClassFlag>(value);
|
||||
if (enumValueOpt.has_value()) {
|
||||
return enumValueOpt.value();
|
||||
}
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
void LoadClassData(std::string_view classPath, ClassAttributes &attributes, PlayerCombatData &combat)
|
||||
{
|
||||
const std::string filename = StrCat("txtdata\\classes\\", classPath, "\\attributes.tsv");
|
||||
tl::expected<DataFile, DataFile::Error> dataFileResult = DataFile::loadOrDie(filename);
|
||||
std::expected<DataFile, DataFile::Error> dataFileResult = DataFile::loadOrDie(filename);
|
||||
DataFile &dataFile = dataFileResult.value();
|
||||
dataFile.skipHeaderOrDie(filename);
|
||||
|
||||
@@ -200,7 +200,7 @@ void LoadClassData(std::string_view classPath, ClassAttributes &attributes, Play
|
||||
void LoadClassStartingLoadoutData(std::string_view classPath, PlayerStartingLoadoutData &startingLoadoutData)
|
||||
{
|
||||
const std::string filename = StrCat("txtdata\\classes\\", classPath, "\\starting_loadout.tsv");
|
||||
tl::expected<DataFile, DataFile::Error> dataFileResult = DataFile::loadOrDie(filename);
|
||||
std::expected<DataFile, DataFile::Error> dataFileResult = DataFile::loadOrDie(filename);
|
||||
DataFile &dataFile = dataFileResult.value();
|
||||
dataFile.skipHeaderOrDie(filename);
|
||||
|
||||
@@ -218,7 +218,7 @@ void LoadClassStartingLoadoutData(std::string_view classPath, PlayerStartingLoad
|
||||
void LoadClassSpriteData(std::string_view classPath, PlayerSpriteData &spriteData)
|
||||
{
|
||||
const std::string filename = StrCat("txtdata\\classes\\", classPath, "\\sprites.tsv");
|
||||
tl::expected<DataFile, DataFile::Error> dataFileResult = DataFile::loadOrDie(filename);
|
||||
std::expected<DataFile, DataFile::Error> dataFileResult = DataFile::loadOrDie(filename);
|
||||
DataFile &dataFile = dataFileResult.value();
|
||||
dataFile.skipHeaderOrDie(filename);
|
||||
|
||||
@@ -242,7 +242,7 @@ void LoadClassSpriteData(std::string_view classPath, PlayerSpriteData &spriteDat
|
||||
void LoadClassAnimData(std::string_view classPath, PlayerAnimData &animData)
|
||||
{
|
||||
const std::string filename = StrCat("txtdata\\classes\\", classPath, "\\animations.tsv");
|
||||
tl::expected<DataFile, DataFile::Error> dataFileResult = DataFile::loadOrDie(filename);
|
||||
std::expected<DataFile, DataFile::Error> dataFileResult = DataFile::loadOrDie(filename);
|
||||
DataFile &dataFile = dataFileResult.value();
|
||||
dataFile.skipHeaderOrDie(filename);
|
||||
|
||||
@@ -280,7 +280,7 @@ void LoadClassAnimData(std::string_view classPath, PlayerAnimData &animData)
|
||||
void LoadClassSounds(std::string_view classPath, ankerl::unordered_dense::map<HeroSpeech, SfxID> &sounds)
|
||||
{
|
||||
const std::string filename = StrCat("txtdata\\classes\\", classPath, "\\sounds.tsv");
|
||||
tl::expected<DataFile, DataFile::Error> dataFileResult = DataFile::loadOrDie(filename);
|
||||
std::expected<DataFile, DataFile::Error> dataFileResult = DataFile::loadOrDie(filename);
|
||||
DataFile &dataFile = dataFileResult.value();
|
||||
dataFile.skipHeaderOrDie(filename);
|
||||
|
||||
|
||||
@@ -5,11 +5,10 @@
|
||||
*/
|
||||
#include "tables/spelldat.h"
|
||||
|
||||
#include <expected>
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "data/file.hpp"
|
||||
#include "data/iterators.hpp"
|
||||
#include "data/record_reader.hpp"
|
||||
@@ -33,26 +32,26 @@ void AddNullSpell()
|
||||
}
|
||||
|
||||
// A temporary solution for parsing soundID until we have a more general one.
|
||||
tl::expected<SfxID, std::string> ParseSpellSoundId(std::string_view value)
|
||||
std::expected<SfxID, std::string> ParseSpellSoundId(std::string_view value)
|
||||
{
|
||||
if (value == "CastFire") return SfxID::CastFire;
|
||||
if (value == "CastHealing") return SfxID::CastHealing;
|
||||
if (value == "CastLightning") return SfxID::CastLightning;
|
||||
if (value == "CastSkill") return SfxID::CastSkill;
|
||||
return tl::make_unexpected("Unknown enum value (only a few are supported for now)");
|
||||
return std::unexpected("Unknown enum value (only a few are supported for now)");
|
||||
}
|
||||
|
||||
tl::expected<SpellDataFlags, std::string> ParseSpellDataFlag(std::string_view value)
|
||||
std::expected<SpellDataFlags, std::string> ParseSpellDataFlag(std::string_view value)
|
||||
{
|
||||
if (value == "Fire") return SpellDataFlags::Fire;
|
||||
if (value == "Lightning") return SpellDataFlags::Lightning;
|
||||
if (value == "Magic") return SpellDataFlags::Magic;
|
||||
if (value == "Targeted") return SpellDataFlags::Targeted;
|
||||
if (value == "AllowedInTown") return SpellDataFlags::AllowedInTown;
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
tl::expected<MissileID, std::string> ParseMissileId(std::string_view value)
|
||||
std::expected<MissileID, std::string> ParseMissileId(std::string_view value)
|
||||
{
|
||||
if (value == "Arrow") return MissileID::Arrow;
|
||||
if (value == "Firebolt") return MissileID::Firebolt;
|
||||
@@ -162,7 +161,7 @@ tl::expected<MissileID, std::string> ParseMissileId(std::string_view value)
|
||||
if (value == "BlueExplosion") return MissileID::BlueExplosion;
|
||||
if (value == "BlueExplosion2") return MissileID::BlueExplosion2;
|
||||
if (value == "OrangeExplosion") return MissileID::OrangeExplosion;
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -170,7 +169,7 @@ tl::expected<MissileID, std::string> ParseMissileId(std::string_view value)
|
||||
/** Data related to each spell ID. */
|
||||
std::vector<SpellData> SpellsData;
|
||||
|
||||
tl::expected<SpellID, std::string> ParseSpellId(std::string_view value)
|
||||
std::expected<SpellID, std::string> ParseSpellId(std::string_view value)
|
||||
{
|
||||
if (value == "Null") return SpellID::Null;
|
||||
if (value == "Firebolt") return SpellID::Firebolt;
|
||||
@@ -224,7 +223,7 @@ tl::expected<SpellID, std::string> ParseSpellId(std::string_view value)
|
||||
if (value == "RuneOfNova") return SpellID::RuneOfNova;
|
||||
if (value == "RuneOfImmolation") return SpellID::RuneOfImmolation;
|
||||
if (value == "RuneOfStone") return SpellID::RuneOfStone;
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
void LoadSpellData()
|
||||
|
||||
@@ -6,13 +6,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "sound_effect_enums.h"
|
||||
#include "utils/enum_traits.h"
|
||||
|
||||
@@ -88,7 +87,7 @@ enum class SpellID : int8_t {
|
||||
Invalid = -1,
|
||||
};
|
||||
|
||||
tl::expected<SpellID, std::string> ParseSpellId(std::string_view value);
|
||||
std::expected<SpellID, std::string> ParseSpellId(std::string_view value);
|
||||
|
||||
enum class MagicType : uint8_t {
|
||||
Fire,
|
||||
|
||||
@@ -25,7 +25,7 @@ std::vector<Speech> Speeches;
|
||||
/** Contains the mapping between text ID strings and indices, used for parsing additional text data. */
|
||||
ankerl::unordered_dense::map<std::string, int16_t> AdditionalTextIdStringsToIndices;
|
||||
|
||||
tl::expected<_speech_id, std::string> ParseSpeechId(std::string_view value)
|
||||
std::expected<_speech_id, std::string> ParseSpeechId(std::string_view value)
|
||||
{
|
||||
if (value.empty()) {
|
||||
return TEXT_NONE;
|
||||
@@ -41,7 +41,7 @@ tl::expected<_speech_id, std::string> ParseSpeechId(std::string_view value)
|
||||
return static_cast<_speech_id>(findIt->second);
|
||||
}
|
||||
|
||||
return tl::make_unexpected("Invalid value.");
|
||||
return std::unexpected("Invalid value.");
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <string>
|
||||
|
||||
#include <expected.hpp>
|
||||
#include <magic_enum/magic_enum.hpp>
|
||||
|
||||
#include "sound_effect_enums.h"
|
||||
@@ -435,7 +435,7 @@ struct Speech {
|
||||
|
||||
extern std::vector<Speech> Speeches;
|
||||
|
||||
tl::expected<_speech_id, std::string> ParseSpeechId(std::string_view value);
|
||||
std::expected<_speech_id, std::string> ParseSpeechId(std::string_view value);
|
||||
|
||||
void LoadTextData();
|
||||
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
#include "tables/townerdat.hpp"
|
||||
|
||||
#include <charconv>
|
||||
#include <expected>
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include <expected.hpp>
|
||||
#include <magic_enum/magic_enum.hpp>
|
||||
|
||||
#include "data/file.hpp"
|
||||
@@ -31,13 +31,13 @@ namespace {
|
||||
* @return The parsed enum value, or an error message
|
||||
*/
|
||||
template <typename EnumT>
|
||||
tl::expected<EnumT, std::string> ParseEnum(std::string_view value)
|
||||
std::expected<EnumT, std::string> ParseEnum(std::string_view value)
|
||||
{
|
||||
const auto enumValueOpt = magic_enum::enum_cast<EnumT>(value);
|
||||
if (enumValueOpt.has_value()) {
|
||||
return enumValueOpt.value();
|
||||
}
|
||||
return tl::make_unexpected("Unknown enum value");
|
||||
return std::unexpected("Unknown enum value");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <expected>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
@@ -15,7 +16,6 @@
|
||||
#include <vector>
|
||||
|
||||
#include <ankerl/unordered_dense.h>
|
||||
#include <expected.hpp>
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
@@ -122,7 +122,7 @@ void Ini::Values::append(const Ini::Value &value)
|
||||
std::get<std::vector<Value>>(rep_).push_back(value);
|
||||
}
|
||||
|
||||
tl::expected<Ini, std::string> Ini::parse(std::string_view buffer)
|
||||
std::expected<Ini, std::string> Ini::parse(std::string_view buffer)
|
||||
{
|
||||
Ini::FileData fileData;
|
||||
ankerl::unordered_dense::map<std::string, ValuesData, StringViewHash, StringViewEquals> *sectionEntries = nullptr;
|
||||
@@ -160,10 +160,10 @@ tl::expected<Ini, std::string> Ini::parse(std::string_view buffer)
|
||||
++keyEnd;
|
||||
}
|
||||
if (keyEnd == lineEnd) {
|
||||
return tl::make_unexpected(fmt::format("line {}: unclosed section name {}", lineNum, std::string_view(keyBegin, keyEnd - keyBegin)));
|
||||
return std::unexpected(fmt::format("line {}: unclosed section name {}", lineNum, std::string_view(keyBegin, keyEnd - keyBegin)));
|
||||
}
|
||||
if (const char *after = SkipTrailingWhitespace(keyEnd + 1, lineEnd); after != lineEnd) {
|
||||
return tl::make_unexpected(fmt::format("line {}: content after section [{}]: {}", lineNum, std::string_view(keyBegin, keyEnd - keyBegin), std::string_view(after, lineEnd - after)));
|
||||
return std::unexpected(fmt::format("line {}: content after section [{}]: {}", lineNum, std::string_view(keyBegin, keyEnd - keyBegin), std::string_view(after, lineEnd - after)));
|
||||
}
|
||||
const std::string_view sectionName = std::string_view(keyBegin, keyEnd - keyBegin);
|
||||
auto it = fileData.sections.find(sectionName);
|
||||
@@ -180,10 +180,10 @@ tl::expected<Ini, std::string> Ini::parse(std::string_view buffer)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sectionEntries == nullptr) return tl::unexpected(fmt::format("line {}: key not in any section", lineNum));
|
||||
if (sectionEntries == nullptr) return std::unexpected(fmt::format("line {}: key not in any section", lineNum));
|
||||
const char *eqPos = static_cast<const char *>(memchr(keyBegin, '=', lineEnd - keyBegin));
|
||||
if (eqPos == nullptr) {
|
||||
return tl::make_unexpected(fmt::format("line {}: key {} has no value", lineNum, std::string_view(keyBegin, lineEnd - keyBegin)));
|
||||
return std::unexpected(fmt::format("line {}: key {} has no value", lineNum, std::string_view(keyBegin, lineEnd - keyBegin)));
|
||||
}
|
||||
const char *keyEnd = SkipTrailingWhitespace(keyBegin, eqPos);
|
||||
const std::string_view key = std::string_view(keyBegin, keyEnd - keyBegin);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <optional>
|
||||
#include <span>
|
||||
#include <string>
|
||||
@@ -11,7 +12,6 @@
|
||||
#include <vector>
|
||||
|
||||
#include <ankerl/unordered_dense.h>
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "utils/string_view_hash.hpp"
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
friend class Ini;
|
||||
};
|
||||
|
||||
static tl::expected<Ini, std::string> parse(std::string_view buffer);
|
||||
static std::expected<Ini, std::string> parse(std::string_view buffer);
|
||||
[[nodiscard]] std::string serialize() const;
|
||||
|
||||
/** @return all the keys associated with this section in the ini */
|
||||
|
||||
@@ -2,11 +2,10 @@
|
||||
|
||||
#include <charconv>
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <string_view>
|
||||
#include <system_error>
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
namespace devilution {
|
||||
|
||||
enum class ParseIntError {
|
||||
@@ -15,7 +14,7 @@ enum class ParseIntError {
|
||||
};
|
||||
|
||||
template <typename IntT>
|
||||
using ParseIntResult = tl::expected<IntT, ParseIntError>;
|
||||
using ParseIntResult = std::expected<IntT, ParseIntError>;
|
||||
|
||||
template <typename IntT>
|
||||
ParseIntResult<IntT> ParseInt(
|
||||
@@ -28,11 +27,11 @@ ParseIntResult<IntT> ParseInt(
|
||||
*endOfParse = result.ptr;
|
||||
}
|
||||
if (result.ec == std::errc::invalid_argument)
|
||||
return tl::unexpected(ParseIntError::ParseError);
|
||||
return std::unexpected(ParseIntError::ParseError);
|
||||
if (result.ec == std::errc::result_out_of_range || value < min || value > max)
|
||||
return tl::unexpected(ParseIntError::OutOfRange);
|
||||
return std::unexpected(ParseIntError::OutOfRange);
|
||||
if (result.ec != std::errc())
|
||||
return tl::unexpected(ParseIntError::ParseError);
|
||||
return std::unexpected(ParseIntError::ParseError);
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -53,7 +52,7 @@ ParseIntResult<IntT> ParseFixed6(std::string_view str, const char **endOfParse =
|
||||
}
|
||||
|
||||
if (str.empty()) {
|
||||
return tl::unexpected { ParseIntError::ParseError };
|
||||
return std::unexpected { ParseIntError::ParseError };
|
||||
}
|
||||
|
||||
constexpr IntT minIntegerValue = std::numeric_limits<IntT>::min() >> 6;
|
||||
@@ -82,7 +81,7 @@ ParseIntResult<IntT> ParseFixed6(std::string_view str, const char **endOfParse =
|
||||
|
||||
if (!haveDigits) {
|
||||
// early return in case we got a string like "-.abc", don't want to set the end pointer in this case
|
||||
return tl::unexpected { ParseIntError::ParseError };
|
||||
return std::unexpected { ParseIntError::ParseError };
|
||||
}
|
||||
|
||||
if (endOfParse != nullptr) {
|
||||
@@ -100,7 +99,7 @@ ParseIntResult<IntT> ParseFixed6(std::string_view str, const char **endOfParse =
|
||||
|
||||
// rounding could give us a value of 64 for the fraction part (e.g. 0.993 rounds to 1.0) so we need to ensure this doesn't overflow
|
||||
if (fractionPart >= 64 && (integerPart >= maxIntegerValue || (std::is_signed_v<IntT> && integerPart <= minIntegerValue))) {
|
||||
return tl::unexpected { ParseIntError::OutOfRange };
|
||||
return std::unexpected { ParseIntError::OutOfRange };
|
||||
} else {
|
||||
IntT fixedValue = integerPart << 6;
|
||||
if (isNegative) {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#define RETURN_IF_ERROR(expr) \
|
||||
if (auto result = expr; DVL_PREDICT_FALSE(!result.has_value())) { \
|
||||
return tl::make_unexpected(std::move(result).error()); \
|
||||
return std::unexpected(std::move(result).error()); \
|
||||
}
|
||||
|
||||
#define STATUS_MACROS_CONCAT_NAME_INNER(x, y) x##y
|
||||
@@ -13,7 +13,7 @@
|
||||
#define ASSIGN_OR_RETURN_IMPL(result, lhs, rhs) \
|
||||
auto result = rhs; /* NOLINT(bugprone-macro-parentheses): assignment */ \
|
||||
if (DVL_PREDICT_FALSE(!result.has_value())) { /* NOLINT(bugprone-macro-parentheses): assignment */ \
|
||||
return tl::make_unexpected(std::move(result).error()); \
|
||||
return std::unexpected(std::move(result).error()); \
|
||||
} \
|
||||
lhs = std::move(result).value(); /* NOLINT(bugprone-macro-parentheses): assignment */
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <expected>
|
||||
#include <string>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
@@ -13,8 +14,6 @@
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "engine/surface.hpp"
|
||||
#include "utils/endian_swap.hpp"
|
||||
#include "utils/pcx.hpp"
|
||||
@@ -23,13 +22,13 @@
|
||||
namespace devilution {
|
||||
namespace {
|
||||
|
||||
tl::expected<void, std::string> CheckedFWrite(const void *ptr, size_t size, SDL_IOStream *out)
|
||||
std::expected<void, std::string> CheckedFWrite(const void *ptr, size_t size, SDL_IOStream *out)
|
||||
{
|
||||
if (SDL_WriteIO(out, ptr, size) != size) {
|
||||
const char *errorMessage = SDL_GetError();
|
||||
if (errorMessage == nullptr)
|
||||
errorMessage = "";
|
||||
tl::expected<void, std::string> result = tl::make_unexpected(std::string("write failed with: ").append(errorMessage));
|
||||
std::expected<void, std::string> result = std::unexpected(std::string("write failed with: ").append(errorMessage));
|
||||
SDL_ClearError();
|
||||
return result;
|
||||
}
|
||||
@@ -43,7 +42,7 @@ tl::expected<void, std::string> CheckedFWrite(const void *ptr, size_t size, SDL_
|
||||
* @param out File stream to write to
|
||||
* @return True on success
|
||||
*/
|
||||
tl::expected<void, std::string> WritePcxHeader(int16_t width, int16_t height, SDL_IOStream *out)
|
||||
std::expected<void, std::string> WritePcxHeader(int16_t width, int16_t height, SDL_IOStream *out)
|
||||
{
|
||||
PCXHeader buffer;
|
||||
|
||||
@@ -68,7 +67,7 @@ tl::expected<void, std::string> WritePcxHeader(int16_t width, int16_t height, SD
|
||||
* @param out File stream for the PCX file.
|
||||
* @return True if successful, else false
|
||||
*/
|
||||
tl::expected<void, std::string> WritePcxPalette(SDL_Color *palette, SDL_IOStream *out)
|
||||
std::expected<void, std::string> WritePcxPalette(SDL_Color *palette, SDL_IOStream *out)
|
||||
{
|
||||
uint8_t pcxPalette[1 + 256 * 3];
|
||||
|
||||
@@ -131,7 +130,7 @@ uint8_t *WritePcxLine(uint8_t *src, uint8_t *dst, int width)
|
||||
* @param out File stream for the PCX file.
|
||||
* @return True if successful, else false
|
||||
*/
|
||||
tl::expected<void, std::string> WritePcxPixels(const Surface &buf, SDL_IOStream *out)
|
||||
std::expected<void, std::string> WritePcxPixels(const Surface &buf, SDL_IOStream *out)
|
||||
{
|
||||
const int width = buf.w();
|
||||
const std::unique_ptr<uint8_t[]> pBuffer { new uint8_t[static_cast<size_t>(2 * width)] };
|
||||
@@ -139,7 +138,7 @@ tl::expected<void, std::string> WritePcxPixels(const Surface &buf, SDL_IOStream
|
||||
for (int height = buf.h(); height > 0; height--) {
|
||||
const uint8_t *pBufferEnd = WritePcxLine(pixels, pBuffer.get(), width);
|
||||
pixels += buf.pitch();
|
||||
tl::expected<void, std::string> result = CheckedFWrite(pBuffer.get(), pBufferEnd - pBuffer.get(), out);
|
||||
std::expected<void, std::string> result = CheckedFWrite(pBuffer.get(), pBufferEnd - pBuffer.get(), out);
|
||||
if (!result.has_value()) return result;
|
||||
}
|
||||
return {};
|
||||
@@ -147,10 +146,10 @@ tl::expected<void, std::string> WritePcxPixels(const Surface &buf, SDL_IOStream
|
||||
|
||||
} // namespace
|
||||
|
||||
tl::expected<void, std::string>
|
||||
std::expected<void, std::string>
|
||||
WriteSurfaceToFilePcx(const Surface &buf, SDL_IOStream *outStream)
|
||||
{
|
||||
tl::expected<void, std::string> result = WritePcxHeader(buf.w(), buf.h(), outStream);
|
||||
std::expected<void, std::string> result = WritePcxHeader(buf.w(), buf.h(), outStream);
|
||||
if (!result.has_value()) return result;
|
||||
result = WritePcxPixels(buf, outStream);
|
||||
if (!result.has_value()) return result;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <expected>
|
||||
#include <string>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
@@ -8,13 +9,11 @@
|
||||
#include "utils/sdl_compat.h"
|
||||
#endif
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "engine/surface.hpp"
|
||||
|
||||
namespace devilution {
|
||||
|
||||
tl::expected<void, std::string>
|
||||
std::expected<void, std::string>
|
||||
WriteSurfaceToFilePcx(const Surface &buf, SDL_IOStream *outStream);
|
||||
|
||||
} // namespace devilution
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "utils/surface_to_png.hpp"
|
||||
|
||||
#include <expected>
|
||||
#include <string>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
@@ -12,8 +13,6 @@
|
||||
#include "utils/sdl_compat.h"
|
||||
#endif
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "engine/surface.hpp"
|
||||
|
||||
namespace devilution {
|
||||
@@ -22,7 +21,7 @@ namespace devilution {
|
||||
extern "C" int IMG_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst);
|
||||
#endif
|
||||
|
||||
tl::expected<void, std::string>
|
||||
std::expected<void, std::string>
|
||||
WriteSurfaceToFilePng(const Surface &buf, SDL_IOStream *dst)
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
@@ -31,7 +30,7 @@ WriteSurfaceToFilePng(const Surface &buf, SDL_IOStream *dst)
|
||||
const bool ok = IMG_SavePNG_RW(buf.surface, dst, /*freedst=*/1) == 0;
|
||||
#endif
|
||||
if (!ok) {
|
||||
tl::expected<void, std::string> result = tl::make_unexpected(std::string(SDL_GetError()));
|
||||
std::expected<void, std::string> result = std::unexpected(std::string(SDL_GetError()));
|
||||
SDL_ClearError();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <cstdio>
|
||||
#include <expected>
|
||||
#include <string>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
@@ -8,8 +9,6 @@
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "engine/surface.hpp"
|
||||
|
||||
namespace devilution {
|
||||
@@ -19,7 +18,7 @@ namespace devilution {
|
||||
*
|
||||
* Takes ownership of `dst` and closes it when done.
|
||||
*/
|
||||
tl::expected<void, std::string>
|
||||
std::expected<void, std::string>
|
||||
WriteSurfaceToFilePng(const Surface &buf,
|
||||
#ifdef USE_SDL3
|
||||
SDL_IOStream *
|
||||
|
||||
@@ -200,7 +200,7 @@ TEST(DataFileTest, ParseInt)
|
||||
}
|
||||
|
||||
DataFile &dataFile = result.value();
|
||||
auto unused = dataFile.parseHeader(nullptr, nullptr, [](std::string_view) -> tl::expected<uint8_t, ColumnDefinition::Error> { return tl::unexpected { ColumnDefinition::Error::UnknownColumn }; });
|
||||
auto unused = dataFile.parseHeader(nullptr, nullptr, [](std::string_view) -> std::expected<uint8_t, ColumnDefinition::Error> { return std::unexpected { ColumnDefinition::Error::UnknownColumn }; });
|
||||
|
||||
EXPECT_TRUE(unused.has_value()) << "Should be able to parse and discard the header from the sample.tsv file";
|
||||
|
||||
@@ -334,7 +334,7 @@ TEST(DataFileTest, ParseHeaderThenIterateOverRecords)
|
||||
{ "1", "", "3" },
|
||||
};
|
||||
|
||||
auto parseHeaderResult = dataFile.parseHeader(nullptr, nullptr, [](std::string_view) -> tl::expected<uint8_t, ColumnDefinition::Error> { return tl::unexpected { ColumnDefinition::Error::UnknownColumn }; });
|
||||
auto parseHeaderResult = dataFile.parseHeader(nullptr, nullptr, [](std::string_view) -> std::expected<uint8_t, ColumnDefinition::Error> { return std::unexpected { ColumnDefinition::Error::UnknownColumn }; });
|
||||
EXPECT_TRUE(parseHeaderResult.has_value()) << "Expected to be able to parse and discard the header record";
|
||||
|
||||
unsigned row = 0;
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ std::string ReplaceNewlines(std::string_view s)
|
||||
|
||||
TEST(IniTest, BasicTest)
|
||||
{
|
||||
tl::expected<Ini, std::string> result = Ini::parse(R"(
|
||||
std::expected<Ini, std::string> result = Ini::parse(R"(
|
||||
; Section A comment
|
||||
[sectionA]
|
||||
key1 = value1
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
@@ -15,7 +16,6 @@
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include <expected.hpp>
|
||||
#include <function_ref.hpp>
|
||||
|
||||
#include "engine/load_file.hpp"
|
||||
@@ -397,7 +397,7 @@ TEST_P(TextRenderIntegrationTest, RenderAndCompareTest)
|
||||
SDL_IOStream *actual = SDL_IOFromFile(actualPath.c_str(), "wb");
|
||||
ASSERT_NE(actual, nullptr) << SDL_GetError();
|
||||
|
||||
const tl::expected<void, std::string> result = WriteSurfaceToFilePng(out, actual);
|
||||
const std::expected<void, std::string> result = WriteSurfaceToFilePng(out, actual);
|
||||
ASSERT_TRUE(result.has_value()) << result.error();
|
||||
|
||||
// We compare pixels rather than PNG file contents because different
|
||||
|
||||
Reference in New Issue
Block a user