diff --git a/.clang-format b/.clang-format deleted file mode 100644 index d48bed8..0000000 --- a/.clang-format +++ /dev/null @@ -1,130 +0,0 @@ ---- -AccessModifierOffset: 0 -AlignAfterOpenBracket: BlockIndent -AlignArrayOfStructures: None -AlignConsecutiveAssignments: None -AlignConsecutiveMacros: None -AlignConsecutiveBitFields: None -AlignConsecutiveDeclarations: None -AlignEscapedNewlines: DontAlign -AlignOperands: DontAlign -AlignTrailingComments: false -AllowAllArgumentsOnNextLine: true -AllowAllParametersOfDeclarationOnNextLine: true -AllowShortBlocksOnASingleLine: Empty -AllowShortCaseLabelsOnASingleLine: false -AllowShortEnumsOnASingleLine: false -AllowShortFunctionsOnASingleLine: Empty -AllowShortIfStatementsOnASingleLine: Never -AllowShortLambdasOnASingleLine: All -AllowShortLoopsOnASingleLine: false -AlwaysBreakAfterReturnType: None -AlwaysBreakBeforeMultilineStrings: true -AlwaysBreakTemplateDeclarations: MultiLine -AttributeMacros: [] -BinPackArguments: false -BinPackParameters: false -BitFieldColonSpacing: After -BraceWrapping: - AfterCaseLabel: false - AfterClass: false - AfterControlStatement: Never - AfterEnum: false - AfterFunction: false - AfterNamespace: false - AfterStruct: false - AfterUnion: false - AfterExternBlock: false - BeforeCatch: false - BeforeElse: false - BeforeLambdaBody: false - BeforeWhile: false - IndentBraces: false - SplitEmptyFunction: false - SplitEmptyRecord: false - SplitEmptyNamespace: false -BreakAfterJavaFieldAnnotations: true -#BreakArrays: false -BreakBeforeBinaryOperators: All -BreakBeforeBraces: Custom -BreakBeforeConceptDeclarations: true -BreakBeforeTernaryOperators: true -BreakConstructorInitializers: AfterColon -BreakInheritanceList: AfterColon -BreakStringLiterals: true -ColumnLimit: 90 -CompactNamespaces: false -ConstructorInitializerIndentWidth: 4 -ContinuationIndentWidth: 4 -Cpp11BracedListStyle: false -DeriveLineEnding: false -DerivePointerAlignment: false -DisableFormat: false # wtf -EmptyLineAfterAccessModifier: Never -EmptyLineBeforeAccessModifier: Always -ExperimentalAutoDetectBinPacking: false -FixNamespaceComments: false -ForEachMacros: ["BOOST_FOREACH"] -IfMacros: [] -IncludeBlocks: Regroup -IndentAccessModifiers: false -IndentCaseBlocks: false -IndentCaseLabels: true -IndentExternBlock: Indent -IndentGotoLabels: true -IndentPPDirectives: BeforeHash -#IndentRequiresClause: false -IndentWidth: 4 -IndentWrappedFunctionNames: false -#InsertBraces: false -InsertTrailingCommas: Wrapped -JavaImportGroups: ["java"] -JavaScriptQuotes: Double -JavaScriptWrapImports: true -KeepEmptyLinesAtTheStartOfBlocks: false -LambdaBodyIndentation: OuterScope -MaxEmptyLinesToKeep: 1 -NamespaceIndentation: All -PackConstructorInitializers: NextLine -PointerAlignment: Left -QualifierAlignment: Left -ReferenceAlignment: Left -ReflowComments: true -#RemoveSemicolon: true -#RequiresClausePosition: OwnLine -#RequiresExpressionIndentation: OuterScope -SeparateDefinitionBlocks: Always -SortIncludes: CaseInsensitive -SortJavaStaticImport: Before -SortUsingDeclarations: true -SpaceAfterCStyleCast: true -SpaceAfterLogicalNot: false -SpaceAfterTemplateKeyword: false -SpaceAroundPointerQualifiers: After -SpaceBeforeAssignmentOperators: true -SpaceBeforeCaseColon: false -SpaceBeforeCpp11BracedList: false -SpaceBeforeCtorInitializerColon: false -SpaceBeforeInheritanceColon: false -SpaceBeforeParens: ControlStatementsExceptControlMacros -SpaceBeforeRangeBasedForLoopColon: true -SpaceBeforeSquareBrackets: false -SpaceInEmptyBlock: false -SpaceInEmptyParentheses: false -SpacesInAngles: Never -SpacesInCStyleCastParentheses: false -SpacesInConditionalStatement: false -SpacesInContainerLiterals: false -SpacesInLineCommentPrefix: - Minimum: 0 - Maximum: -1 -SpacesInParentheses: false -SpacesInSquareBrackets: false -Standard: c++20 -StatementAttributeLikeMacros: [] -StatementMacros: [] -TabWidth: 4 -TypenameMacros: [] -UseCRLF: false # wtf -UseTab: Never -WhitespaceSensitiveMacros: ["BOOST_PP_STRINGSIZE"] diff --git a/.gitignore b/.gitignore index 9785597..a4bc542 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ -build -.cache +zig-out/ +zig-cache/ + diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 002dc7c..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -cmake_minimum_required(VERSION 3.0.0) -project(PORTINGTOOLS) - -file(GLOB_RECURSE sources src/*) - -find_package(Boost 1.80 COMPONENTS log filesystem REQUIRED) - -include_directories(${Boost_INCLUDE_DIR}) - -add_executable(portingtools ${sources}) - -set_property(TARGET portingtools PROPERTY CXX_STANDARD 20) - -target_link_libraries(portingtools LINK_PUBLIC ${Boost_LIBRARIES}) diff --git a/README.md b/README.md index 6f276b9..f7c1b11 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,8 @@ This tool is meant to make porting mods easier for MineteckReloaded. -Also, it helped me learn some c++, so don't expect good code. - ## Installation -- `cmake -S. -Bbuild` -- `cmake --build build` -- start the server with `build/portingtools serve` -- map stuff with `build/portingtools map` -- resolve ResourceLocations with `build/portingtools resourceloc` +- `zig build` +- start the server with `zig-out/bin/portingtools serve` +- map stuff with `zig-out/bin/portingtools map` diff --git a/build.zig b/build.zig new file mode 100644 index 0000000..9984a8c --- /dev/null +++ b/build.zig @@ -0,0 +1,34 @@ +const std = @import("std"); + +pub fn build(b: *std.build.Builder) void { + // Standard target options allows the person running `zig build` to choose + // what target to build for. Here we do not override the defaults, which + // means any target is allowed, and the default is native. Other options + // for restricting supported target set are available. + const target = b.standardTargetOptions(.{}); + + // Standard release options allow the person running `zig build` to select + // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. + const mode = b.standardReleaseOptions(); + + const exe = b.addExecutable("portingtools", "src/main.zig"); + exe.setTarget(target); + exe.setBuildMode(mode); + exe.install(); + + const run_cmd = exe.run(); + run_cmd.step.dependOn(b.getInstallStep()); + if (b.args) |args| { + run_cmd.addArgs(args); + } + + const run_step = b.step("run", "Run the app"); + run_step.dependOn(&run_cmd.step); + + const exe_tests = b.addTest("src/main.zig"); + exe_tests.setTarget(target); + exe_tests.setBuildMode(mode); + + const test_step = b.step("test", "Run unit tests"); + test_step.dependOn(&exe_tests.step); +} diff --git a/src/StringPacket.zig b/src/StringPacket.zig new file mode 100644 index 0000000..8f93c9a --- /dev/null +++ b/src/StringPacket.zig @@ -0,0 +1,21 @@ +const std = @import("std"); + +str: []const u8, + +const Self = @This(); + +pub fn read(reader: anytype, alloc: std.mem.Allocator) !Self { + const strlen = try reader.readIntBig(u32); + + const str = try alloc.alloc(u8, strlen); + errdefer alloc.free(str); + + try reader.readNoEof(str); + + return .{ .str = str }; +} + +pub fn write(self: *const Self, writer: anytype) !void { + try writer.writeIntBig(u32, @intCast(u32, self.str.len)); + try writer.writeAll(self.str); +} diff --git a/src/ansi.hpp b/src/ansi.hpp deleted file mode 100644 index 74a79a7..0000000 --- a/src/ansi.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#define ANSI_CODE_DEF inline const char* - -namespace ansi { - ANSI_CODE_DEF reset = "\033[0m"; - - ANSI_CODE_DEF cyan = "\033[0;36m"; - ANSI_CODE_DEF green = "\033[0;32m"; - ANSI_CODE_DEF yellow = "\033[0;33m"; -} - -#undef ANSI_CODE_DEF diff --git a/src/client.cpp b/src/client.cpp deleted file mode 100644 index 36b28f6..0000000 --- a/src/client.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "data.hpp" -#include "resourceloc.hpp" - -#include -#include -#include -#include -#include -#include -#include - -namespace client { - void sendMsg(int msqid, data::RequestMapMsg* msg) { - if (msgsnd(msqid, msg, sizeof(data::RequestMapMsg) - sizeof(long), 0) < 0) { - throw std::runtime_error(std::string("send error ") + strerror(errno)); - } - } - - std::string recvMsg(int msqid) { - data::ResponseMapMsg msg; - - if (msgrcv( - msqid, - &msg, - sizeof(data::ResponseMapMsg) - sizeof(long), - data::clientbound_msg, - 0 - ) - < 0) { - throw std::runtime_error(std::string("receive error ") + strerror(errno)); - } - - return std::string(&msg.data[0], msg.datalen); - } - - void map(key_t key) { - std::string inp; - std::cin >> inp; - - auto msqid = msgget(key, 0664); - - if (msqid < 0) { - throw std::runtime_error("msgget fail. is the server running?"); - } - - data::RequestMapMsg req; - req.msgtype = data::serverbound_msg; - req.datalen = inp.size(); - std::copy(inp.begin(), inp.end(), req.data); - - sendMsg(msqid, &req); - std::cout << recvMsg(msqid) << std::endl; - } - - void resolveResourceLoc(key_t key) { - std::string inp; - std::cin >> inp; - - std::cout << resourceloc::resolve(inp) << std::endl; - } -} diff --git a/src/client.hpp b/src/client.hpp deleted file mode 100644 index c6d2dd4..0000000 --- a/src/client.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -#include -#include - -namespace client { - void map(key_t key); - void resolveResourceLoc(key_t key); -} diff --git a/src/csv.cpp b/src/csv.cpp deleted file mode 100644 index 665b6bc..0000000 --- a/src/csv.cpp +++ /dev/null @@ -1,91 +0,0 @@ -#include "csv.hpp" - -#include -#include -#include - -namespace csv { - enum class CSVState { - UnquotedField, - QuotedField, - QuotedQuote - }; - - // this function has been made in collaboration with - // StackOverflow https://stackoverflow.com/a/30338543 - void readCSVRow(const std::string& row, std::vector& fields) { - fields.push_back(""); - CSVState state = CSVState::UnquotedField; - size_t i = 0; // index of the current field - - for (char c : row) { - switch (state) { - case CSVState::UnquotedField: - switch (c) { - case ',': // end of field - fields.push_back(""); - i++; - break; - - case '"': - state = CSVState::QuotedField; - break; - - default: - fields[i].push_back(c); - break; - } - - break; - - case CSVState::QuotedField: - switch (c) { - case '"': - state = CSVState::QuotedQuote; - break; - - default: - fields[i].push_back(c); - break; - } - - break; - - case CSVState::QuotedQuote: - switch (c) { - case ',': // , after closing quote - fields.push_back(""); - i++; - state = CSVState::UnquotedField; - break; - - case '"': // "" -> " - fields[i].push_back('"'); - state = CSVState::QuotedField; - break; - - default: // end of quote - state = CSVState::UnquotedField; - break; - } - - break; - } - } - } - - bool CsvReader::operator>>(std::vector& line) { - line.clear(); - - if (!m_stream) { - return false; - } - - std::string row; - std::getline(m_stream, row); - - readCSVRow(row, line); - - return !!m_stream; - } -} diff --git a/src/csv.hpp b/src/csv.hpp deleted file mode 100644 index 2030d72..0000000 --- a/src/csv.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once -#include -#include -#include - -namespace csv { - class CsvReader { - private: - std::ifstream m_stream; - - public: - CsvReader(auto stream): m_stream(stream){}; - ~CsvReader() = default; - - bool operator>>(std::vector& line); - }; -} diff --git a/src/csv_reader.zig b/src/csv_reader.zig new file mode 100644 index 0000000..fc75747 --- /dev/null +++ b/src/csv_reader.zig @@ -0,0 +1,79 @@ +const std = @import("std"); + +pub const Record = struct { + cols: [][]u8, + + pub fn deinit(self: Record, alloc: std.mem.Allocator) void { + for (self.cols) |col| { + alloc.free(col); + } + + alloc.free(self.cols); + } +}; + +pub fn csvReader(reader: anytype) CsvReader(@TypeOf(reader)) { + return .{ .reader = reader }; +} + +pub fn CsvReader(comptime Reader: type) type { + return struct { + reader: Reader, + + const Self = @This(); + + pub fn next(self: *Self, alloc: std.mem.Allocator) !?Record { + var prev_quote = false; + var in_quote = false; + + var cols = std.ArrayList([]u8).init(alloc); + defer cols.deinit(); + + var buf = std.ArrayList(u8).init(alloc); + defer buf.deinit(); + + while (true) { + var ch_buf: [1]u8 = undefined; + + if (try self.reader.read(&ch_buf) == 0) { + if (buf.items.len != 0) { + try cols.append(try buf.toOwnedSlice()); + return Record{ .cols = try cols.toOwnedSlice() }; + } + + return null; + } + + const ch = ch_buf[0]; + + switch (ch) { + '"' => { + if (prev_quote) { + try buf.append('"'); + } else { + prev_quote = true; + in_quote = !in_quote; + } + }, + ',' => { + prev_quote = false; + if (in_quote) { + try buf.append(','); + } else { + defer buf.clearRetainingCapacity(); + try cols.append(try alloc.dupe(u8, buf.items)); + } + }, + '\n' => { + try cols.append(try buf.toOwnedSlice()); + return Record{ .cols = try cols.toOwnedSlice() }; + }, + else => { + prev_quote = false; + try buf.append(ch); + }, + } + } + } + }; +} diff --git a/src/data.cpp b/src/data.cpp deleted file mode 100644 index 33f6b31..0000000 --- a/src/data.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "data.hpp" - -#include -#include -#include -#include - -namespace data { - key_t getIpcKeyFromExeName(char* argv0) { - auto k = ftok(argv0, 'X'); - - if (k < 0) { - throw std::runtime_error("failed to get IPC key"); - } - - return k; - } -} diff --git a/src/data.hpp b/src/data.hpp deleted file mode 100644 index 3a10dd7..0000000 --- a/src/data.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once -#include -#include - -namespace data { - const int serverbound_msg = 1; - const int clientbound_msg = 2; - - key_t getIpcKeyFromExeName(char* argv0); - - struct RequestMapMsg { - long msgtype; - - unsigned int datalen; - char data[128]; - }; - - struct ResponseMapMsg { - long msgtype; - - unsigned int datalen; - char data[128]; - }; -} diff --git a/src/main.cpp b/src/main.cpp deleted file mode 100644 index b2b3b42..0000000 --- a/src/main.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "client.hpp" -#include "data.hpp" -#include "server.hpp" - -#include -#include -#include - -void main2(int argc, char* argv[]) { - if (argc < 2) { - throw std::runtime_error("not enough arguments!"); - } - - if (strcmp(argv[1], "serve") == 0) { - server::run(data::getIpcKeyFromExeName(argv[0])); - } else if (strcmp(argv[1], "map") == 0) { - client::map(data::getIpcKeyFromExeName(argv[0])); - } else if (strcmp(argv[1], "resourceloc") == 0) { - client::resolveResourceLoc(data::getIpcKeyFromExeName(argv[0])); - } else { - throw std::runtime_error("unknown command!"); - } -} - -int main(int argc, char* argv[]) { - try { - main2(argc, argv); - return 0; - } catch (const std::exception& e) { - BOOST_LOG_TRIVIAL(fatal) << "Exception: " << e.what(); - return 1; - } -} diff --git a/src/main.zig b/src/main.zig new file mode 100644 index 0000000..92b2d3b --- /dev/null +++ b/src/main.zig @@ -0,0 +1,179 @@ +const std = @import("std"); +const csv_reader = @import("csv_reader.zig"); + +const StringPacket = @import("StringPacket.zig"); + +pub const log_level = .debug; + +const Mapping = struct { + mapped: []const u8, + doc: ?[]const u8, +}; + +fn getAddr(alloc: std.mem.Allocator) !std.net.Address { + const sockpath = try std.fs.path.join(alloc, &.{ + std.os.getenv("XDG_RUNTIME_DIR") orelse return error.MissingRuntimeDir, + "portingtools.sock", + }); + defer alloc.free(sockpath); + + return try std.net.Address.initUnix(sockpath); +} + +pub fn main() !void { + if (std.os.argv.len < 2) { + return error.InvalidArgs; + } + + const cmd = std.mem.span(std.os.argv[1]); + + if (std.mem.eql(u8, cmd, "serve")) { + try runServer(); + } else if (std.mem.eql(u8, cmd, "map")) { + try map(); + } else { + return error.InvalidCommand; + } +} + +fn map() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer _ = gpa.deinit(); + + const alloc = gpa.allocator(); + + const stdin = std.io.getStdIn().reader(); + + var buf: [128]u8 = undefined; + const request = (try stdin.readUntilDelimiterOrEof(&buf, '\n')) orelse return error.NoInput; + + const addr = try getAddr(alloc); + + const sockfd = try std.os.socket( + std.os.AF.UNIX, + std.os.SOCK.STREAM | std.os.SOCK.CLOEXEC, + 0, + ); + defer std.os.closeSocket(sockfd); + + try std.os.connect(sockfd, &addr.any, addr.getOsSockLen()); + + const stream = std.net.Stream{ .handle = sockfd }; + + const pkt = StringPacket{ .str = std.mem.trim(u8, request, &std.ascii.whitespace) }; + try pkt.write(stream.writer()); + + const res = try StringPacket.read(stream.reader(), alloc); + defer alloc.free(res.str); + + try std.io.getStdOut().writer().print("{s}\n", .{res.str}); +} + +fn runServer() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer _ = gpa.deinit(); + + const alloc = gpa.allocator(); + + var mappings = std.StringHashMap(Mapping).init(alloc); + defer mappings.deinit(); + + var data_arena = std.heap.ArenaAllocator.init(alloc); + defer data_arena.deinit(); + + var renames = std.StringHashMap([]const u8).init(alloc); + defer renames.deinit(); + + if (std.fs.cwd().openFile("renames.csv", .{})) |renames_file| { + defer renames_file.close(); + + var reader = csv_reader.csvReader(std.io.bufferedReader(renames_file.reader())); + + while (try reader.next(data_arena.allocator())) |rec| { + if (rec.cols.len != 2) { + std.log.warn("found rename with invalid record length, skipping", .{}); + continue; + } + + if (renames.contains(rec.cols[0])) { + std.log.warn("duplicate rename '{s}'", .{rec.cols[0]}); + continue; + } + + try renames.put(rec.cols[0], rec.cols[1]); + } + + std.log.info("loaded {} renames", .{renames.count()}); + } else |err| { + std.log.warn("couldn't open renames file: {}, skipping", .{err}); + } + + var mappings_dir = try std.fs.cwd().openIterableDir("mappings", .{}); + defer mappings_dir.close(); + + var mappings_iter = mappings_dir.iterate(); + + while (try mappings_iter.next()) |entry| { + const fpath = try std.fs.path.join(alloc, &.{ "mappings", entry.name }); + defer alloc.free(fpath); + + var mapfile = try std.fs.cwd().openFile(fpath, .{}); + defer mapfile.close(); + + var reader = csv_reader.csvReader(std.io.bufferedReader(mapfile.reader())); + + while (try reader.next(data_arena.allocator())) |rec| { + if (rec.cols.len < 2) { + std.log.warn("found mapping with invalid length, skipping", .{}); + continue; + } + + if (mappings.contains(rec.cols[0])) { + std.log.warn("duplicate mapping '{s}'", .{rec.cols[0]}); + continue; + } + + const mapping = Mapping{ + .mapped = rec.cols[1], + .doc = if (rec.cols.len >= 4) rec.cols[3] else null, + }; + + try mappings.put(rec.cols[0], mapping); + } + } + + std.log.info("loaded {} mappings", .{mappings.count()}); + + var server = std.net.StreamServer.init(.{}); + defer server.deinit(); + + const addr = try getAddr(alloc); + try server.listen(addr); + std.log.info("listening on {}", .{addr}); + + while (true) { + const con = try server.accept(); + const req = try StringPacket.read(con.stream.reader(), alloc); + defer alloc.free(req.str); + + if (mappings.get(req.str)) |mapping| { + const res = StringPacket{ .str = mapping.mapped }; + try res.write(con.stream.writer()); + + std.log.info( + \\ + \\ Unmapped: {s} + \\ Mapped: {s} + \\ + \\ Doc: {s} + , .{ + req.str, + mapping.mapped, + mapping.doc orelse "", + }); + } else { + const res = StringPacket{ .str = "" }; + try res.write(con.stream.writer()); + } + } +} diff --git a/src/mappings.cpp b/src/mappings.cpp deleted file mode 100644 index 5f364c3..0000000 --- a/src/mappings.cpp +++ /dev/null @@ -1,121 +0,0 @@ -#include "mappings.hpp" - -#include "ansi.hpp" -#include "csv.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace fs = boost::filesystem; - -namespace mappings { - Mappings Mappings::load() { - std::map mappings; - std::map renames; - - // load mappings - fs::directory_iterator end_itr; - - try { - for (fs::directory_iterator itr("mappings"); itr != end_itr; ++itr) { - if (fs::is_directory(itr->status()) - || !boost::algorithm::ends_with(itr->path().string(), ".csv")) - continue; - - csv::CsvReader csv(itr->path().string()); - - std::vector l; - - while (csv >> l) { - if (l.size() < 2) { - BOOST_LOG_TRIVIAL(warning) << "found invalid mapping"; - continue; - } - - mappings[l[0]] = { - l[0], l[1], l.size() >= 4 ? std::optional(l[3]) : std::nullopt - }; - } - } - } catch (boost::filesystem::filesystem_error& e) { - if (e.code() == boost::system::errc::no_such_file_or_directory) { - throw std::runtime_error( - std::string("The mappings directory is missing!\n") + e.what() - ); - } - - throw; - } - - if (fs::is_regular_file("renames.csv")) { - csv::CsvReader csv("renames.csv"); - - std::vector l; - - while (csv >> l) { - if (l.size() < 2) { - BOOST_LOG_TRIVIAL(warning) << "found invalid rename"; - continue; - } - - renames[l[0]] = l[1]; - } - } else { - BOOST_LOG_TRIVIAL(warning) << "no renames found, skipping"; - } - - BOOST_LOG_TRIVIAL(info) << "loaded " << mappings.size() << " mappings and " - << renames.size() << " renames"; - return { mappings, renames }; - } - - void showMapInfo(Mapping mapping, std::optional rename) { - auto doc = mapping.doc.has_value() - ? std::string(ansi::yellow) + "\n\n\t" + *mapping.doc + "\n" - : ""; - - if (rename.has_value()) { - BOOST_LOG_TRIVIAL(info) - << "\nFound mapping:\n" - << ansi::cyan << "\n\tOriginal\t" << ansi::green << mapping.orig - << ansi::cyan << "\n\tRemapped\t" << ansi::green << mapping.name - << ansi::cyan << "\n\tRenamed \t" << ansi::green << *rename << doc - << ansi::reset; - } else { - BOOST_LOG_TRIVIAL(info) << "\nFound mapping:\n" - << ansi::cyan << "\n\tOriginal\t" << ansi::green - << mapping.orig << ansi::cyan << "\n\tRemapped\t" - << ansi::green << mapping.name << doc << ansi::reset; - } - } - - std::string Mappings::map(std::string inp) { - if (!this->m_mappings.count(inp)) { - BOOST_LOG_TRIVIAL(warning) << "unknown mapping '" << inp << "'"; - return ""; - } - - auto mapped = this->m_mappings[inp]; - - if (this->m_renames.count(mapped.name)) { - BOOST_LOG_TRIVIAL(info) - << "found rename " << mapped.name << " -> " << m_renames[mapped.name]; - showMapInfo(mapped, m_renames[mapped.name]); - return m_renames[mapped.name]; - } - - showMapInfo(mapped, std::nullopt); - return mapped.name; - } -} diff --git a/src/mappings.hpp b/src/mappings.hpp deleted file mode 100644 index 58c2d6a..0000000 --- a/src/mappings.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once -#include -#include -#include - -namespace mappings { - struct Mapping { - std::string orig; - std::string name; - std::optional doc; - }; - - class Mappings { - std::map m_mappings; - std::map m_renames; - - public: - Mappings( - std::map mappings, - std::map renames - ): - m_mappings(mappings), m_renames(renames) {} - - ~Mappings() = default; - static Mappings load(); - std::string map(std::string inp); - }; -} diff --git a/src/resourceloc.cpp b/src/resourceloc.cpp deleted file mode 100644 index 9a0a482..0000000 --- a/src/resourceloc.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "resourceloc.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace resourceloc { - std::string resolve(std::string inp) { - boost::algorithm::trim_if(inp, boost::is_any_of(" \n\r\"")); - - std::vector components; - boost::algorithm::split(components, inp, boost::is_any_of("/")); - - if (components.size() < 3 || components[0] != "" || components[1] != "mods") { - BOOST_LOG_TRIVIAL(warning) << "invalid resourceloc"; - return ""; - } - - std::string path_component; - - for (unsigned int i = 3; i < components.size(); i++) { - path_component += components[i]; - - if (i != components.size() - 1) { - path_component += "/"; - } - } - - return boost::str( - boost::format("new ResourceLocation(\"%1%\", \"%2%\")") % components[2] - % path_component - ); - } -} diff --git a/src/resourceloc.hpp b/src/resourceloc.hpp deleted file mode 100644 index 93a7c0b..0000000 --- a/src/resourceloc.hpp +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once -#include - -namespace resourceloc { - std::string resolve(std::string inp); -} diff --git a/src/server.cpp b/src/server.cpp deleted file mode 100644 index 099fb08..0000000 --- a/src/server.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "server.hpp" - -#include "data.hpp" -#include "mappings.hpp" -#include "resourceloc.hpp" - -#include -#include -#include -#include -#include -#include -#include - -namespace server { - void sendToClient(int msqid, std::string msg) { - data::ResponseMapMsg pkt; - pkt.msgtype = data::clientbound_msg; - pkt.datalen = msg.size(); - std::copy(msg.begin(), msg.end(), pkt.data); - - if (msgsnd(msqid, &pkt, sizeof(data::ResponseMapMsg) - sizeof(long), 0) < 0) { - BOOST_LOG_TRIVIAL(error) << "failed to send response " << strerror(errno); - } - } - - void run(key_t key) { - BOOST_LOG_TRIVIAL(info) << "starting server"; - - auto msqid = msgget(key, 0664 | IPC_CREAT); - - if (msqid < 0) { - throw std::runtime_error("msgget fail"); - } - - BOOST_LOG_TRIVIAL(info) << "msqid " << msqid; - - auto mappings = mappings::Mappings::load(); - - data::RequestMapMsg msg; - - for (;;) { - if (msgrcv( - msqid, - &msg, - sizeof(data::RequestMapMsg) - sizeof(long), - data::serverbound_msg, - 0 - ) - < 0) { - BOOST_LOG_TRIVIAL(error) << "receive error " << strerror(errno); - continue; - } - - std::string s(msg.data, msg.datalen); - BOOST_LOG_TRIVIAL(info) << "got request to map '" << s << "'"; - sendToClient(msqid, mappings.map(s)); - } - } -} diff --git a/src/server.hpp b/src/server.hpp deleted file mode 100644 index 2094149..0000000 --- a/src/server.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -#include -#include - -namespace server { - void run(key_t key); -}