Compare commits

..

11 Commits

Author SHA1 Message Date
Shwoomple f784948c3e lib/file: fix cutByte filesize bug 2022-10-30 16:10:33 +00:00
Shwoomple d794bce288 lib/file.cpp: Implement cutByte function 2022-10-30 16:10:33 +00:00
BodgeMaster 99c8f562d6 setupenv: Fix wrong path 2022-10-30 06:10:04 +01:00
BodgeMaster 57a86cba47 setupenv: Add workaround for LD_LIBRARY_PATH on Cygwin 2022-10-30 05:56:34 +01:00
BodgeMaster 5ff8a871ad lib/javacompat: Make this a header library
Cygwin build issues were caused by lib/nbt impleicitly linking against this
2022-10-30 04:55:58 +01:00
BodgeMaster e0994e5db8 resources/java/netty-tests: Add maven project
This is going to be used for figuring out how Netty operates
and whether we should just make our own version or port the
existing Netty to C++ and use it as a dependency or whether
we even need it at all.
2022-10-30 03:17:25 +01:00
BodgeMaster 80c8a46ab2 Documentation and resources: Updates and minor clean-up 2022-10-30 02:53:56 +02:00
BodgeMaster 4abb1f223c lib/nbt: Lists can no longer be constructed from invalid sets of data
The constructor `NBT::Tag::List::List(tiny_utf8::string, std::vector<NBT::Tag::Generic*>)`
is now private and has a wrapper function `NBT::Tag::List::constructWithData(tiny_utf8::string, std::vector<NBT::Tag::Generic*>)`
that performs a sanity check on the data it is given.
2022-10-28 04:08:06 +02:00
BodgeMaster 4da50d3c6b test/dumpnbt: Add unit test (fixing #63) 2022-10-28 02:45:52 +02:00
BodgeMaster c9b56d4d7f tools/dumpnbt: Remove unused CLI flag 2022-10-28 02:45:25 +02:00
BodgeMaster 7bccaca7b9 fossvg and fossvgd: Add stub programs for client and server 2022-10-28 01:53:20 +02:00
24 changed files with 7178 additions and 499 deletions

4
.gitignore vendored
View File

@ -17,6 +17,8 @@
# Java bytecode
*.class
# Maven's build files
/resources/java/netty-tests/target/
# ignore nano's temp files
*.swp
@ -24,4 +26,4 @@
#vscode
.vscode
writeTest
writeTest

View File

@ -14,8 +14,8 @@ Immediate goals:
- [ ] send a surface to stand on
- [ ] handle chat
- NBT library
- [ ] parse NBT
- [ ] decode and encode data
- [x] parse NBT
- [x] decode and encode data
## Project Setup Instructions

View File

@ -1,33 +1,53 @@
# Tests
# Resources
Data used for testing and understanding the internals of Minecraft/FOSS-VG,
also contains code to produce such data
## java/
Programs to produce data for figuring out how to interact
with Java-specific things
- `JavaStringGenerator.java`: A simple tool that reads from stdin and outputs Java-style UTF-8 to stdout
- `netty-tests/`: Figure out how Netty operates
## NBT_data/
Data used to test the NBT library
`bare_int64_tag`: What the name says
`bare_int64_tag_and_int32_tag`: What the name says
`simple_nbt`: A simple NBT file containing all tag types
`nested_compounds_and_lists`: A combination of nested compound and list tags (parser stress test)
`servers.dat`: Pulled from my Minecraft installation
`servers.dat_nbt_decoded.txt`: The same data manually decoded (This was done to get a better understanding how NBT works, might come in handy.)
`level.dat`: Pulled from one of my world saves (gzip-compressed)
`level.dat_decompressed`: The same data decompressed
## unicode_data/
This directory contains two files with unicode data. One is in Java format, the other is normal UTF-8.
Files with unicode data
- Bare ("normal") UTF-8
- Java format
## all_bytes
Every possible 8-bit byte in ascending order
## check_endianness.cpp
A simple tool to determine the endianness of the system and write the endianness header for FOSS-VG
A simple tool to determine the endianness of the system and write
the endianness header for FOSS-VG
Supports: Little Endian, Big Endian, PDP Endian, Honeywell Endian
Note that, while it can detect PDP and Honeywell endianness, the FOSS-VG project itself does not support these.
Usage: `check_endianness > header_file`
Usage example: `check_endianness > header_file`
## JavaStringGenerator.java
A simple tool written in Java that takes an input as UTF-8 and outputs it in Java-style UTF-8.
Usage example: `echo -ne "\x00" | java JavaStringGenerator > output_file`
## NBT_data
Data used to test the NBT library.
`servers.dat`: My current servers.dat as pulled from my Minecraft installation
`servers.dat_nbt_decoded.txt`: The same file manually decoded (I did this to get a better understanding how NBT works, might come in handy in the future.)
`simple_nbt`: A simple NBT file containing all tags
`nested_compounds_and_lists`: A combination of nested compound and list tags intended to be challenging to parse
Note that, while this tool should in theory be able to detect
PDP and Honeywell-316-style endianness, the FOSS-VG project itself
does not support these.

View File

@ -1,354 +0,0 @@
#############################################################################
# Examples for all types of tags: #
#############################################################################
[0: End]:
|Header: 1 byte
|Payload: 0 bytes
'Total: 1 byte
[0: 8 Bit Integer] name:
|Header: 7 bytes
|Payload: 1 byte
|Total: 8 bytes
'Value: 0
[0: 16 Bit Integer] name:
|Header: 7 bytes
|Payload: 2 bytes
|Total: 9 bytes
'Value: 0
[0: 32 Bit Integer] name:
|Header: 7 bytes
|Payload: 4 bytes
|Total: 11 bytes
'Value: 0
[0: 64 Bit Integer] name:
|Header: 7 bytes
|Payload: 8 bytes
|Total: 15 bytes
'Value: 0
[0: Float] name:
|Header: 7 bytes
|Payload: 4 bytes
|Total: 11 bytes
'Value: 0
[0: Double] name:
|Header: 7 bytes
|Payload: 8 bytes
|Total: 15 bytes
'Value: 0
[0: Array of 8 Bit Integers] name:
|Header: 7 bytes
|Payload: 7 bytes
|Total: 14 bytes
|Length: 3
'Values:
|0
|0
'0
[0: String] name:
|Header: 7 bytes
|Payload: 14 bytes
|Total: 21 bytes
'Value: Hello World!
[0: List] name:
|Header: 7 bytes
|Payload: 8 bytes
|Total: 15 bytes
|Contained Type: 8 Bit Integer
|Length: 3
|
|[12: 8 Bit Integer]:
| |Payload: 1 byte
| |Total: 1 byte
| 'Value: 0
|
|[13: 8 Bit Integer]:
| |Payload: 1 byte
| |Total: 1 byte
| 'Value: 0
|
'[14: 8 Bit Integer]:
|Payload: 1 byte
|Total: 1 byte
'Value: 0
[0: Compound] name:
|Header: 7 bytes
|Payload: 25 bytes
|Total: 32 bytes
|Length: 4
|
|[7: 8 Bit Integer] name:
| |Header: 7 bytes
| |Payload: 1 byte
| |Total: 8 bytes
| 'Value: 0
|
|[15: 8 Bit Integer] name:
| |Header: 7 bytes
| |Payload: 1 byte
| |Total: 8 bytes
| 'Value: 0
|
|[23: 8 Bit Integer] name:
| |Header: 7 bytes
| |Payload: 1 byte
| |Total: 8 bytes
| 'Value: 0
|
'[31: End]:
|Header: 1 byte
|Payload: 0 bytes
'Total: 1 byte
[0: Array of 32 Bit Integers] name:
|Header: 7 bytes
|Payload: 16 bytes
|Total: 23 bytes
|Length: 3
'Values:
|0
|0
'0
[0: Array of 64 Bit Integers] name:
|Header: 7 bytes
|Payload: 28 bytes
|Total: 35 bytes
|Length: 3
'Values:
|0
|0
'0
#############################################################################
# Output for simple_nbt (what it's supposed to look like) #
#############################################################################
[0: Compound]:
|Header: 3 bytes
|Payload: 475 bytes
|Total: 478 bytes
|Length: 15
|
|[3: String] Spaces and special characters are allowed in tag names, right?:
| |Header: 65 bytes
| |Payload: 24 bytes
| |Total: 89 bytes
| 'Value: Idk. Lets find out.
|
|[92: Compound] compound:
| |Header: 11 bytes
| |Payload: 45 bytes
| |Total: 56 bytes
| |Length: 3
| |
| |[103: 32 Bit Integer] some_number:
| | |Header: 14 bytes
| | |Payload: 4 bytes
| | |Total: 18 bytes
| | 'Value: -754506943
| |
| |[121: String] some_text:
| | |Header: 12 bytes
| | |Payload: 14 bytes
| | |Total: 26 bytes
| | 'Value: eat a cookie
| |
| '[147: End]:
| |Header: 1 byte
| |Payload: 0 bytes
| 'Total: 1 byte
|
|[148: Double] double:
| |Header: 9 bytes
| |Payload: 8 bytes
| |Total: 17 bytes
| 'Value: 623593.6542742235
|
|[165: Float] float:
| |Header: 8 bytes
| |Payload: 4 bytes
| |Total: 12 bytes
| 'Value: 35.2678337097168
|
|[177: 16 Bit Integer] int16:
| |Header: 8 bytes
| |Payload: 2 bytes
| |Total: 10 bytes
| 'Value: 2000
|
|[187: 32 Bit Integer] int32:
| |Header: 8 bytes
| |Payload: 4 bytes
| |Total: 12 bytes
| 'Value: 10101010
|
|[199: Array of 32 Bit Integers] int32_array:
| |Header: 14 bytes
| |Payload: 20 bytes
| |Total: 34 bytes
| |Length: 4
| 'Values:
| |398452796
| |43259
| |2147483647
| '1634890337
|
|[233: 64 Bit Integer] int64:
| |Header: 8 bytes
| |Payload: 8 bytes
| |Total: 16 bytes
| 'Value: 810001800766
|
|[249: Array of 64 Bit Integers] int64_array:
| |Header: 14 bytes
| |Payload: 44 bytes
| |Total: 58 bytes
| |Length: 5
| 'Values:
| |239865
| |23586749
| |9223372036854775807
| |188944201329624
| '3116157694992754
|
|[307: 8 Bit Integer] int8:
| |Header: 7 bytes
| |Payload: 1 byte
| |Total: 8 bytes
| 'Value: 100
|
|[315: Array of 8 Bit Integers] int8_array:
| |Header: 13 bytes
| |Payload: 12 bytes
| |Total: 25 bytes
| |Length: 8
| 'Values:
| |113
| |53
| |119
| |98
| |84
| |100
| |245
| '50
|
|[340: List] list_int8:
| |Header: 12 bytes
| |Payload: 10 bytes
| |Total: 22 bytes
| |Contained Type: 8 Bit Integer
| |Length: 5
| |
| |[357: 8 Bit Integer]:
| | |Payload: 1 byte
| | |Total: 1 byte
| | 'Value: 65
| |
| |[358: 8 Bit Integer]:
| | |Payload: 1 byte
| | |Total: 1 byte
| | 'Value: 96
| |
| |[359: 8 Bit Integer]:
| | |Payload: 1 byte
| | |Total: 1 byte
| | 'Value: 78
| |
| |[360: 8 Bit Integer]:
| | |Payload: 1 byte
| | |Total: 1 byte
| | 'Value: 127
| |
| '[361: 8 Bit Integer]:
| |Payload: 1 byte
| |Total: 1 byte
| 'Value: -6
|
|[362: List] list_strings:
| |Header: 15 bytes
| |Payload: 77 bytes
| |Total: 92 bytes
| |Contained Type: String
| |Length: 12
| |
| |[382: String]:
| | |Payload: 8 bytes
| | |Total: 8 bytes
| | 'Value: Pacman
| |
| |[390: String]:
| | |Payload: 5 bytes
| | |Total: 5 bytes
| | 'Value: ate
| |
| |[395: String]:
| | |Payload: 5 bytes
| | |Total: 5 bytes
| | 'Value: all
| |
| |[400: String]:
| | |Payload: 5 bytes
| | |Total: 5 bytes
| | 'Value: the
| |
| |[405: String]:
| | |Payload: 6 bytes
| | |Total: 6 bytes
| | 'Value: dots
| |
| |[411: String]:
| | |Payload: 4 bytes
| | |Total: 4 bytes
| | 'Value: so
| |
| |[415: String]:
| | |Payload: 5 bytes
| | |Total: 5 bytes
| | 'Value: now
| |
| |[420: String]:
| | |Payload: 8 bytes
| | |Total: 8 bytes
| | 'Value: hes
| |
| |[428: String]:
| | |Payload: 8 bytes
| | |Total: 8 bytes
| | 'Value: coming
| |
| |[436: String]:
| | |Payload: 5 bytes
| | |Total: 5 bytes
| | 'Value: for
| |
| |[441: String]:
| | |Payload: 5 bytes
| | |Total: 5 bytes
| | 'Value: the
| |
| '[446: String]:
| |Payload: 8 bytes
| |Total: 8 bytes
| 'Value: words.
|
|[454: String] string:
| |Header: 9 bytes
| |Payload: 14 bytes
| |Total: 23 bytes
| 'Value: Hello World!
|
'[477: End]:
|Header: 1 byte
|Payload: 0 bytes
'Total: 1 byte

View File

@ -0,0 +1,5 @@
# Netty Testing
This sub-project is used to learn how Netty works
Build with Maven (`mvn compile`). Run with the build scripts.

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>foss_vg</groupId>
<artifactId>netty-tests</artifactId>
<version>1.0-SNAPSHOT</version>
<name>netty-tests</name>
<url>https://lostcave.ddnss.de/git/BodgeMaster/FOSS-VG</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.84.Final</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<!--
Removed all the bloat bc we don't need it.
Maven will probably choose a default version for the things I removed.
I don't care as targets other than compile and clean aren't needed here.
-->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

View File

@ -0,0 +1,22 @@
# Copyright 2022, FOSS-VG Developers and Contributers
#
# Author(s):
# BodgeMaster
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# version 3 along with this program.
# If not, see https://www.gnu.org/licenses/agpl-3.0.en.html
set -e
cd target/classes
java foss_vg.NettyClient

View File

@ -0,0 +1,22 @@
# Copyright 2022, FOSS-VG Developers and Contributers
#
# Author(s):
# BodgeMaster
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# version 3 along with this program.
# If not, see https://www.gnu.org/licenses/agpl-3.0.en.html
set -e
cd target/classes
java foss_vg.NettyServer

View File

@ -0,0 +1,25 @@
// Copyright 2022, FOSS-VG Developers and Contributers
//
// Author(s):
// BodgeMaster
//
// This program is free software: you can redistribute it and/or modify it
// under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, version 3.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// version 3 along with this program.
// If not, see https://www.gnu.org/licenses/agpl-3.0.en.html
package foss_vg;
public class NettyClient {
public static void main(String[] args) {
}
}

View File

@ -0,0 +1,25 @@
// Copyright 2022, FOSS-VG Developers and Contributers
//
// Author(s):
// BodgeMaster
//
// This program is free software: you can redistribute it and/or modify it
// under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, version 3.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// version 3 along with this program.
// If not, see https://www.gnu.org/licenses/agpl-3.0.en.html
package foss_vg;
public class NettyServer {
public static void main(String[] args) {
}
}

View File

@ -59,10 +59,12 @@ echo ">>> Building tools..."
create_directory bin/tools
# add compile commands to this array
COMPILE_COMMANDS=(
"$CXX_WITH_FLAGS src/tools/dumpnbt.cpp -I./include -Lbin/lib -l:nbt.so -l:javacompat.so -l:cli.so -o bin/tools/dumpnbt"
"$CXX_WITH_FLAGS src/tools/dumpnbt.cpp -I./include -Lbin/lib -l:nbt.so -l:cli.so -o bin/tools/dumpnbt"
"$CXX_WITH_FLAGS src/tools/arraydump.cpp -I./include -Lbin/lib -l:file.so -l:cli.so -o bin/tools/arraydump"
"$CXX_WITH_FLAGS src/tools/baseconvert.cpp -I./include -Lbin/lib -l:cli.so -o bin/tools/baseconvert"
"$CXX_WITH_FLAGS -pthread src/tools/hexnet.cpp -I./include -Lbin/lib -l:cli.so -l:libsockpp.so -o bin/tools/hexnet"
"$CXX_WITH_FLAGS src/fossvg.cpp -I./include -Lbin/lib -l:cli.so -o bin/fossvg"
"$CXX_WITH_FLAGS src/fossvgd.cpp -I./include -Lbin/lib -l:cli.so -o bin/fossvgd"
)
for command in ${!COMPILE_COMMANDS[@]}; do
echo "${COMPILE_COMMANDS[command]}"

View File

@ -33,11 +33,11 @@ echo ">>> Building tests..."
# add compile commands to this array
COMPILE_COMMANDS=(
"$CXX_WITH_FLAGS src/test/nbt_read_write_helpers.cpp -I./include -Lbin/lib -l:nbt.so -l:javacompat.so -o bin/test/nbt_read_write_helpers"
"$CXX_WITH_FLAGS src/test/nbt_read_write_helpers.cpp -I./include -Lbin/lib -l:nbt.so -o bin/test/nbt_read_write_helpers"
"$CXX_WITH_FLAGS src/test/cli_argument_parser.cpp -Lbin/lib -l:cli.so -o bin/test/cli_argument_parser"
"$CXX_WITH_FLAGS src/test/javacompat.cpp -I./include -Lbin/lib -l:javacompat.so -o bin/test/javacompat"
"$CXX_WITH_FLAGS src/test/nbt_tags.cpp -I./include -Lbin/lib -l:nbt.so -l:javacompat.so -o bin/test/nbt_tags"
"$CXX_WITH_FLAGS src/test/nbt_size_helpers.cpp -I./include -Lbin/lib -l:nbt.so -l:javacompat.so -o bin/test/nbt_size_helpers"
"$CXX_WITH_FLAGS src/test/javacompat.cpp -I./include -Lbin/lib -o bin/test/javacompat"
"$CXX_WITH_FLAGS src/test/nbt_tags.cpp -I./include -Lbin/lib -l:nbt.so -o bin/test/nbt_tags"
"$CXX_WITH_FLAGS src/test/nbt_size_helpers.cpp -I./include -Lbin/lib -l:nbt.so -o bin/test/nbt_size_helpers"
"$CXX_WITH_FLAGS src/test/file.cpp -I./include -Lbin/lib -l:file.so -o bin/test/file"
)
for command in ${!COMPILE_COMMANDS[@]}; do

6728
scripts/test/dumpnbt.sh Executable file

File diff suppressed because it is too large Load Diff

View File

@ -41,7 +41,11 @@ function build {
echo "Added aliases and functions."
export PATH="$PROJECT_BASE_DIR/bin/tools:$PROJECT_BASE_DIR/scripts/tools:$PATH"
export PATH="$PROJECT_BASE_DIR/bin:$PROJECT_BASE_DIR/bin/tools:$PROJECT_BASE_DIR/scripts/tools:$PATH"
if uname -s | tr [:upper:] [:lower:] | grep cygwin >/dev/null; then
echo "Adding cygwin workaound for library path."
export PATH="$PROJECT_BASE_DIR/bin/lib:$PATH"
fi
echo "PATH is $PATH"
if [ -z "$LD_LIBRARY_PATH" ]; then

67
src/fossvg.cpp Normal file
View File

@ -0,0 +1,67 @@
// Copyright 2022, FOSS-VG Developers and Contributers
//
// Author(s):
// BodgeMaster
//
// This program is free software: you can redistribute it and/or modify it
// under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, version 3.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// version 3 along with this program.
// If not, see https://www.gnu.org/licenses/agpl-3.0.en.html
#include <iostream>
#include <vector>
#include "./lib/cli.hpp"
#define EXIT_SUCCESS 0
#define EXIT_RUNTIME 1
#define EXIT_USAGE 2
int main(int argc, char* argv[]) {
std::vector<CLI::Flag> flags;
flags.push_back(CLI::Flag('h', "help", "print help and exit"));
flags.push_back(CLI::Flag('l', "license", "print license information and exit"));
std::vector<CLI::Option> options;
std::vector<CLI::Argument> arguments;
CLI::ArgumentsParser cliParser = CLI::ArgumentsParser(argc, argv, flags, options, arguments, "FOSS-VG Client");
if (cliParser.getFlag("help").value) {
std::cout << cliParser.getUsage() << std::endl;
return EXIT_SUCCESS;
}
if (cliParser.getFlag("license").value){
std::cout
<< "Copyright 2022, FOSS-VG Developers and Contributers\n"
<< "\n"
<< "This program is free software: you can redistribute it and/or modify it\n"
<< "under the terms of the GNU Affero General Public License as published\n"
<< "by the Free Software Foundation, version 3.\n"
<< "\n"
<< "This program is distributed in the hope that it will be useful,\n"
<< "but WITHOUT ANY WARRANTY; without even the implied\n"
<< "warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
<< "See the GNU Affero General Public License for more details.\n"
<< "\n"
<< "You should have received a copy of the GNU Affero General Public License\n"
<< "version 3 along with this program.\n"
<< "If not, see https://www.gnu.org/licenses/agpl-3.0.en.html"
<< std::endl;
return EXIT_SUCCESS;
}
if (cliParser.wrongUsage) {
std::cout << cliParser.getUsage() << std::endl;
return EXIT_USAGE;
}
return EXIT_SUCCESS;
}

67
src/fossvgd.cpp Normal file
View File

@ -0,0 +1,67 @@
// Copyright 2022, FOSS-VG Developers and Contributers
//
// Author(s):
// BodgeMaster
//
// This program is free software: you can redistribute it and/or modify it
// under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, version 3.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// version 3 along with this program.
// If not, see https://www.gnu.org/licenses/agpl-3.0.en.html
#include <iostream>
#include <vector>
#include "./lib/cli.hpp"
#define EXIT_SUCCESS 0
#define EXIT_RUNTIME 1
#define EXIT_USAGE 2
int main(int argc, char* argv[]) {
std::vector<CLI::Flag> flags;
flags.push_back(CLI::Flag('h', "help", "print help and exit"));
flags.push_back(CLI::Flag('l', "license", "print license information and exit"));
std::vector<CLI::Option> options;
std::vector<CLI::Argument> arguments;
CLI::ArgumentsParser cliParser = CLI::ArgumentsParser(argc, argv, flags, options, arguments, "FOSS-VG Server");
if (cliParser.getFlag("help").value) {
std::cout << cliParser.getUsage() << std::endl;
return EXIT_SUCCESS;
}
if (cliParser.getFlag("license").value){
std::cout
<< "Copyright 2022, FOSS-VG Developers and Contributers\n"
<< "\n"
<< "This program is free software: you can redistribute it and/or modify it\n"
<< "under the terms of the GNU Affero General Public License as published\n"
<< "by the Free Software Foundation, version 3.\n"
<< "\n"
<< "This program is distributed in the hope that it will be useful,\n"
<< "but WITHOUT ANY WARRANTY; without even the implied\n"
<< "warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
<< "See the GNU Affero General Public License for more details.\n"
<< "\n"
<< "You should have received a copy of the GNU Affero General Public License\n"
<< "version 3 along with this program.\n"
<< "If not, see https://www.gnu.org/licenses/agpl-3.0.en.html"
<< std::endl;
return EXIT_SUCCESS;
}
if (cliParser.wrongUsage) {
std::cout << cliParser.getUsage() << std::endl;
return EXIT_USAGE;
}
return EXIT_SUCCESS;
}

View File

@ -95,6 +95,8 @@ namespace ErrorCodes {
// never be performed (like deleting an end tag from an NBT compound)
const uint8_t NOT_ALLOWED = 11;
const uint8_t MIXED_TYPES = 12;
const uint8_t UNIMPLEMENTED = 254;
const uint8_t UNKNOWN = 255;

View File

@ -1,94 +0,0 @@
//Copyright 2022, FOSS-VG Developers and Contributers
//
//This program is free software: you can redistribute it and/or modify it
//under the terms of the GNU Affero General Public License as published
//by the Free Software Foundation, version 3.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied
//warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//See the GNU Affero General Public License for more details.
//
//You should have received a copy of the GNU Affero General Public License
//version 3 along with this program.
//If not, see https://www.gnu.org/licenses/agpl-3.0.en.html
#include <tinyutf8/tinyutf8.h>
#include <string>
#include "error.hpp"
#include "javacompat.hpp"
#include "../../.endianness"
#ifdef FOSSVG_ENDIAN_BIG_WORD
#error "Honeywell-316-style endianness is not supported. If you feel like it should, feel free to participate in the project to maintain it."
#endif
#ifdef FOSSVG_ENDIAN_LITTLE_WORD
#error "PDP-11-style endianness is not supported. If you feel like it should, feel free to participate in the project to maintain it."
#endif
#ifdef FOSSVG_ENDIAN_UNKNOWN
#error "The endianness of your system could not be determined. Please set it manually. FOSS-VG is currently implemented using some endian-specific functions."
#endif
namespace JavaCompat {
ErrorOr<tiny_utf8::string> importJavaString(uint8_t data[], uint16_t size) {
std::string stdString;
uint16_t encodedSize = static_cast<uint16_t>(data[0])<<8 | static_cast<uint16_t>(data[1]);
if(encodedSize != size){
return ErrorOr<tiny_utf8::string>(true, ErrorCodes::MISMATCHEDSIZE);
}
for(uint16_t i=2; i<size+2; i++){
if(i != 0){
if(data[i] == 0x80 && data[i-1] == 0xc0){
stdString[stdString.length() - 1] = '\0';
continue;
}
}
stdString.push_back((char) data[i]);
}
return ErrorOr<tiny_utf8::string>(tiny_utf8::string(stdString));
}
ErrorOr<std::vector<uint8_t>> exportJavaString(tiny_utf8::string data) {
uint16_t* size = new uint16_t;
uint8_t* sizeBytes = reinterpret_cast<uint8_t*>(size);
std::vector<uint8_t> output = std::vector<uint8_t>();
std::string stdString = data.cpp_str();
if(stdString.size() > 0xFFFF){
return ErrorOr<std::vector<uint8_t>>(true, ErrorCodes::OVERRUN);
}
*size = (uint16_t) stdString.size();
//placeholder size bytes
output.push_back(0x00);
output.push_back(0x00);
for(uint16_t i=0; i<stdString.size(); i++){
if((uint8_t) stdString[i] == 0x00){
*size += 1;
output.push_back(0xc0);
output.push_back(0x80);
continue;
}
output.push_back(stdString[i]);
}
//FIXME: endian-dependent implementation
#ifdef FOSSVG_BIG_ENDIAN
output[0] = *sizeBytes;
output[1] = *(sizeBytes+1);
#else
#ifdef FOSSVG_LITTLE_ENDIAN
output[0] = *(sizeBytes+1);
output[1] = *sizeBytes;
#else
#error "JavaCompat::exportJavaString: An implementation for your endianness is unavailable."
#endif
#endif
return ErrorOr(output);
}
}

View File

@ -13,11 +13,81 @@
//version 3 along with this program.
//If not, see https://www.gnu.org/licenses/agpl-3.0.en.html
#include <vector>
#include <tinyutf8/tinyutf8.h>
#include <string>
#include "error.hpp"
#include "../../.endianness"
#ifdef FOSSVG_ENDIAN_BIG_WORD
#error "Honeywell-316-style endianness is not supported. If you feel like it should, feel free to participate in the project to maintain it."
#endif
#ifdef FOSSVG_ENDIAN_LITTLE_WORD
#error "PDP-11-style endianness is not supported. If you feel like it should, feel free to participate in the project to maintain it."
#endif
#ifdef FOSSVG_ENDIAN_UNKNOWN
#error "The endianness of your system could not be determined. Please set it manually. FOSS-VG is currently implemented using some endian-specific functions."
#endif
namespace JavaCompat {
ErrorOr<tiny_utf8::string> importJavaString(uint8_t data[], uint16_t size);
ErrorOr<std::vector<uint8_t>> exportJavaString(tiny_utf8::string data);
ErrorOr<tiny_utf8::string> importJavaString(uint8_t data[], uint16_t size) {
std::string stdString;
uint16_t encodedSize = static_cast<uint16_t>(data[0])<<8 | static_cast<uint16_t>(data[1]);
if(encodedSize != size){
return ErrorOr<tiny_utf8::string>(true, ErrorCodes::MISMATCHEDSIZE);
}
for(uint16_t i=2; i<size+2; i++){
if(i != 0){
if(data[i] == 0x80 && data[i-1] == 0xc0){
stdString[stdString.length() - 1] = '\0';
continue;
}
}
stdString.push_back((char) data[i]);
}
return ErrorOr<tiny_utf8::string>(tiny_utf8::string(stdString));
}
ErrorOr<std::vector<uint8_t>> exportJavaString(tiny_utf8::string data) {
uint16_t* size = new uint16_t;
uint8_t* sizeBytes = reinterpret_cast<uint8_t*>(size);
std::vector<uint8_t> output = std::vector<uint8_t>();
std::string stdString = data.cpp_str();
if(stdString.size() > 0xFFFF){
return ErrorOr<std::vector<uint8_t>>(true, ErrorCodes::OVERRUN);
}
*size = (uint16_t) stdString.size();
//placeholder size bytes
output.push_back(0x00);
output.push_back(0x00);
for(uint16_t i=0; i<stdString.size(); i++){
if((uint8_t) stdString[i] == 0x00){
*size += 1;
output.push_back(0xc0);
output.push_back(0x80);
continue;
}
output.push_back(stdString[i]);
}
//FIXME: endian-dependent implementation
#ifdef FOSSVG_BIG_ENDIAN
output[0] = *sizeBytes;
output[1] = *(sizeBytes+1);
#else
#ifdef FOSSVG_LITTLE_ENDIAN
output[0] = *(sizeBytes+1);
output[1] = *sizeBytes;
#else
#error "JavaCompat::exportJavaString: An implementation for your endianness is unavailable."
#endif
#endif
return ErrorOr(output);
}
}

View File

@ -861,6 +861,22 @@ namespace NBT {
}
}
ErrorOr<List*> List::constructWithData(tiny_utf8::string name, std::vector<Generic*> data) {
if (data.size() > 0xFFFFFFFF) {
return ErrorOr<List*>(true, ErrorCodes::OVERRUN, nullptr);
}
if (data.size() > 0) {
uint8_t dataType = data[0]->getTagType();
for (uint32_t i=1; i<data.size(); i++) {
if (data[i]->getTagType() != dataType) {
return ErrorOr<List*>(true, ErrorCodes::MIXED_TYPES, nullptr);
}
}
}
return ErrorOr<List*>(new List(name, data));
}
List::~List() {
for (uint64_t i=0; i<this->tags.size(); i++) {
delete this->tags.at(i);
@ -1310,7 +1326,7 @@ namespace NBT {
returnValue = ErrorOr<std::vector<Tag::Generic*>>(true, nextListContents.errorCode);
goto returnError;
}
contents.push_back(new Tag::List("", nextListContents.value));
contents.push_back(Tag::List::constructWithData("", nextListContents.value).value);
*processedDataSize += *containedDataSize;
}
delete containedDataSize;
@ -1427,7 +1443,7 @@ namespace NBT {
returnValue = ErrorOr<std::vector<Tag::Generic*>>(true, listData.errorCode);
goto returnNow;
}
tags.push_back(new Tag::List(tagName.value, listData.value));
tags.push_back(Tag::List::constructWithData(tagName.value, listData.value).value);
*processedTagSize += (uint64_t) nameSize + 3;
}
if (data[currentPosition]==TagType::COMPOUND) {

View File

@ -225,10 +225,10 @@ namespace NBT {
private:
std::vector<Generic*> tags;
uint8_t containedType;
List(tiny_utf8::string name, std::vector<Generic*> data);
public:
List();
List(tiny_utf8::string name, uint8_t type);
List(tiny_utf8::string name, std::vector<Generic*> data);
~List() override;
@ -240,6 +240,7 @@ namespace NBT {
ErrorOrVoid appendPointer(Generic* pointer);
ErrorOrVoid deleteElement(uint64_t position);
uint64_t length();
static ErrorOr<List*> constructWithData(tiny_utf8::string name, std::vector<Generic*> data);
};
class Compound: public Generic {

View File

@ -794,24 +794,26 @@ int main(){
ASSERT(resultError.isError && resultError.errorCode == ErrorCodes::INVALID_TYPE);
//TODO: Check that constructing with a vector of mixed tags
// results in a clearly defined failure mode (issue #60)
NBT::Tag::List list_2 = NBT::Tag::List("list_2", listDataVector);
ASSERT(list_2.getContainedType() == NBT::TagType::INT8);
ASSERT(list_1.length() == 4 && list_2.length() == 4);
ASSERT(!list_2.deleteElement(1).isError);
ASSERT(list_2.deleteElement(3).isError && list_2.deleteElement(3).errorCode == ErrorCodes::OUT_OF_RANGE);
ASSERT(!list_2.getElementPointer(2).isError && dynamic_cast<NBT::Tag::Int8*>(list_2.getElementPointer(2).value)->getValue() == 78);
ASSERT(list_2.getElementPointer(3).isError && list_2.getElementPointer(3).errorCode == ErrorCodes::OUT_OF_RANGE);
ASSERT(!list_2.setElementPointerAt(0, new NBT::Tag::Int8("set_entry", 3)).isError);
ErrorOrVoid resultRange = list_2.setElementPointerAt(3, new NBT::Tag::Int8("out_of_range_entry", 2));
ErrorOr<NBT::Tag::List*> list_2_or_error = NBT::Tag::List::constructWithData("list_2", listDataVector);
ASSERT(!list_2_or_error.isError);
NBT::Tag::List* list_2 = list_2_or_error.value;
ASSERT(list_2->getContainedType() == NBT::TagType::INT8);
ASSERT(list_1.length() == 4 && list_2->length() == 4);
ASSERT(!list_2->deleteElement(1).isError);
ASSERT(list_2->deleteElement(3).isError && list_2->deleteElement(3).errorCode == ErrorCodes::OUT_OF_RANGE);
ASSERT(!list_2->getElementPointer(2).isError && dynamic_cast<NBT::Tag::Int8*>(list_2->getElementPointer(2).value)->getValue() == 78);
ASSERT(list_2->getElementPointer(3).isError && list_2->getElementPointer(3).errorCode == ErrorCodes::OUT_OF_RANGE);
ASSERT(!list_2->setElementPointerAt(0, new NBT::Tag::Int8("set_entry", 3)).isError);
ErrorOrVoid resultRange = list_2->setElementPointerAt(3, new NBT::Tag::Int8("out_of_range_entry", 2));
ASSERT(resultRange.isError);
ASSERT(resultRange.errorCode == ErrorCodes::OUT_OF_RANGE);
ErrorOrVoid resultType = list_2.setElementPointerAt(0, new NBT::Tag::Int16());
ErrorOrVoid resultType = list_2->setElementPointerAt(0, new NBT::Tag::Int16());
ASSERT(resultType.isError);
ASSERT(resultType.errorCode == ErrorCodes::INVALID_TYPE);
ASSERT(list_2.length() == 3);
ASSERT(list_2->length() == 3);
ASSERT(!list_1.serialize(&vector).isError);
ASSERT(!list_2.serialize(&vector).isError);
ASSERT(!list_2->serialize(&vector).isError);
ASSERT(vector.size() == 35);
ASSERT(
vector.at( 0) == 9 &&
@ -852,7 +854,7 @@ int main(){
);
vector.clear();
ASSERT(!list_1.serializeWithoutHeader(&vector).isError);
ASSERT(!list_2.serializeWithoutHeader(&vector).isError);
ASSERT(!list_2->serializeWithoutHeader(&vector).isError);
ASSERT(vector.size() == 17);
ASSERT(
vector.at( 0) == 1 &&

View File

@ -294,7 +294,6 @@ int main(int argc, char* argv[]) {
std::vector<CLI::Flag> flags;
flags.push_back(CLI::Flag('h', "help", "print help and exit"));
flags.push_back(CLI::Flag('l', "license", "print license information and exit"));
flags.push_back(CLI::Flag('x', "hexadecimal", "print numbers in hex format"));
std::vector<CLI::Option> options;
std::vector<CLI::Argument> arguments;
arguments.push_back(CLI::Argument("FILE", "path of the file to dump"));