-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add version 3 of package with old version 2 contents
Due to the way golang handles major versions > v1, the package path *must* contain the major version in the import/module path. This means that importing module version 2 did not work because there was no v2 in the path. To get around this while still maintaining semantic versioning, a package version 3 was created in top-level directory 'v3'. This means import paths for v3 tags will now contain the 'v3' suffix as expected. Additional enhancements were made to the package for v3. Since a breaking change was going to be introduced anyway, some of the package files were reorganized to remove the verbose 'pkg/eolib/...' imports - the directories are all at the top of v3 together now.
- Loading branch information
1 parent
3a9f9b2
commit 9526960
Showing
69 changed files
with
36,603 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,6 @@ | ||
[submodule "eo-protocol"] | ||
path = eo-protocol | ||
url = https://www.github.com/cirras/eo-protocol | ||
[submodule "eo-protocol-v3"] | ||
path = v3/eo-protocol | ||
url = https://www.github.com/cirras/eo-protocol |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
// eolibgo is the top-level package for the Go implementation of eolib. | ||
// | ||
// More details are available in the eolib subdirectory: [pkg/github.com/ethanmoffat/eolib-go/pkg/eolib] | ||
// See the v3 version for more details: [pkg/github.com/ethanmoffat/eolib-go/v3] | ||
package eolibgo |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/xml" | ||
"flag" | ||
"fmt" | ||
"io" | ||
"io/fs" | ||
"os" | ||
"path" | ||
"path/filepath" | ||
"strings" | ||
|
||
"github.com/ethanmoffat/eolib-go/v3/internal/codegen" | ||
eoxml "github.com/ethanmoffat/eolib-go/v3/internal/xml" | ||
) | ||
|
||
var inputDir string | ||
var outputDir string | ||
|
||
func main() { | ||
flag.StringVar(&inputDir, "i", "eo-protocol", "The input directory for eo-protocol files.") | ||
flag.StringVar(&outputDir, "o", "protocol", "The output directory for generated code.") | ||
flag.Parse() | ||
|
||
if _, err := os.Stat(inputDir); err != nil { | ||
fmt.Printf("error: input directory %s does not exist\n", inputDir) | ||
os.Exit(1) | ||
} | ||
|
||
if _, err := os.Stat(outputDir); err != nil { | ||
fmt.Printf("error: output directory %s does not exist\n", outputDir) | ||
os.Exit(1) | ||
} | ||
|
||
fmt.Printf("Using parameters:\n inputDir: %s\n outputDir: %s\n", inputDir, outputDir) | ||
|
||
protocolFiles := []string{} | ||
filepath.WalkDir(path.Join(inputDir, "xml"), func(currentPath string, d fs.DirEntry, err error) error { | ||
if path.Ext(currentPath) == ".xml" { | ||
relativeDir := strings.ReplaceAll(currentPath, path.Join(inputDir, "xml"), "") | ||
protocolFiles = append(protocolFiles, strings.ReplaceAll(relativeDir, "/protocol.xml", "")) | ||
} | ||
return nil | ||
}) | ||
|
||
dirToPackageName := map[string]string{ | ||
"map": "eomap", | ||
"net": "net", | ||
"net/client": "client", | ||
"net/server": "server", | ||
"pub": "pub", | ||
"pub/server": "serverpub", | ||
"": "protocol", | ||
} | ||
|
||
var fullSpec eoxml.Protocol // all XML specs in a single place, for type lookups | ||
var protocs []eoxml.Protocol // each individual protoc file | ||
for _, file := range protocolFiles { | ||
fullInputPath := path.Join(inputDir, "xml", file, "protocol.xml") | ||
|
||
fp, err := os.Open(fullInputPath) | ||
if err != nil { | ||
fmt.Printf("error opening file: %v\n", err) | ||
os.Exit(1) | ||
} | ||
defer fp.Close() | ||
|
||
bytes, err := io.ReadAll(fp) | ||
if err != nil { | ||
fmt.Printf("error reading file: %v\n", err) | ||
os.Exit(1) | ||
} | ||
|
||
var next eoxml.Protocol | ||
if err := xml.Unmarshal(bytes, &next); err != nil { | ||
fmt.Printf("error unmarshalling xml: %v\n", err) | ||
os.Exit(1) | ||
} | ||
|
||
for i := range next.Enums { | ||
next.Enums[i].Package = dirToPackageName[strings.Trim(file, string(os.PathSeparator))] | ||
next.Enums[i].PackagePath = file | ||
} | ||
|
||
for i := range next.Structs { | ||
next.Structs[i].Package = dirToPackageName[strings.Trim(file, string(os.PathSeparator))] | ||
next.Structs[i].PackagePath = file | ||
} | ||
|
||
for i := range next.Packets { | ||
next.Packets[i].Package = dirToPackageName[strings.Trim(file, string(os.PathSeparator))] | ||
next.Packets[i].PackagePath = file | ||
} | ||
|
||
fullSpec.Enums = append(fullSpec.Enums, next.Enums...) | ||
fullSpec.Structs = append(fullSpec.Structs, next.Structs...) | ||
fullSpec.Packets = append(fullSpec.Packets, next.Packets...) | ||
|
||
protocs = append(protocs, next) | ||
} | ||
|
||
for i, file := range protocolFiles { | ||
protoc := protocs[i] | ||
|
||
if err := protoc.Validate(); err != nil { | ||
fmt.Printf("error validating unmarshalled xml: %v\n", err) | ||
os.Exit(1) | ||
} | ||
|
||
fullOutputPath := path.Join(outputDir, file) | ||
|
||
fmt.Printf("generating code :: %s\n", file) | ||
fmt.Printf(" %3d enums\n", len(protoc.Enums)) | ||
if err := codegen.GenerateEnums(fullOutputPath, protoc.Enums); err != nil { | ||
fmt.Printf(" error generating enums: %v\n", err) | ||
} | ||
|
||
fmt.Printf(" %3d structs\n", len(protoc.Structs)) | ||
if err := codegen.GenerateStructs(fullOutputPath, protoc.Structs, fullSpec); err != nil { | ||
fmt.Printf(" error generating structs: %v\n", err) | ||
} | ||
|
||
fmt.Printf(" %3d packets\n", len(protoc.Packets)) | ||
if err := codegen.GeneratePackets(fullOutputPath, protoc.Packets, fullSpec); err != nil { | ||
fmt.Printf(" error generating packets: %v\n", err) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package data | ||
|
||
import "github.com/ethanmoffat/eolib-go/v3/utils" | ||
|
||
// EncodeNumber encodes a number to a sequence of bytes. | ||
func EncodeNumber(number int) []byte { | ||
value := number | ||
|
||
d := 0xFE | ||
if number >= THREE_MAX { | ||
d = value/THREE_MAX + 1 | ||
value = value % THREE_MAX | ||
} | ||
|
||
c := 0xFE | ||
if number >= SHORT_MAX { | ||
c = value/SHORT_MAX + 1 | ||
value = value % SHORT_MAX | ||
} | ||
|
||
b := 0xFE | ||
if number >= CHAR_MAX { | ||
b = value/CHAR_MAX + 1 | ||
value = value % CHAR_MAX | ||
} | ||
|
||
a := value + 1 | ||
|
||
return []byte{byte(a), byte(b), byte(c), byte(d)} | ||
} | ||
|
||
// DecodeNumber decodes a number from a sequence of bytes. | ||
func DecodeNumber(bytes []byte) int { | ||
result := 0 | ||
length := utils.Min(len(bytes), 4) | ||
|
||
for i := 0; i < length; i++ { | ||
value := int(bytes[i]) | ||
|
||
if value == 0xFE { | ||
break | ||
} | ||
|
||
value-- | ||
|
||
if i == 0 { | ||
result += value | ||
} else if i == 1 { | ||
result += CHAR_MAX * value | ||
} else if i == 2 { | ||
result += SHORT_MAX * value | ||
} else if i == 3 { | ||
result += THREE_MAX * value | ||
} | ||
} | ||
|
||
return result | ||
} | ||
|
||
// EncodeString encodes a string by inverting the bytes and then reversing them. | ||
func EncodeString(str []byte) []byte { | ||
inverted := invert(str) | ||
return utils.Reverse(inverted) | ||
} | ||
|
||
// DecodeString decodes a string by reversing the bytes and then inverting them. | ||
func DecodeString(bytes []byte) []byte { | ||
reversed := utils.Reverse(bytes) | ||
return invert(reversed) | ||
} | ||
|
||
func invert(bytes []byte) []byte { | ||
flippy := len(bytes)%2 == 1 | ||
|
||
retBytes := make([]byte, len(bytes)) | ||
copy(retBytes, bytes) | ||
|
||
for i, c := range retBytes { | ||
retBytes[i] = c | ||
|
||
f := 0 | ||
|
||
if flippy { | ||
f = 0x2E | ||
if c >= 0x50 { | ||
f *= -1 | ||
} | ||
} | ||
|
||
if c >= 0x22 && c <= 0x7E { | ||
retBytes[i] = 0x9F - c - byte(f) | ||
} | ||
|
||
flippy = !flippy | ||
} | ||
|
||
return retBytes | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
package data_test | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"testing" | ||
|
||
"github.com/ethanmoffat/eolib-go/v3/data" | ||
"github.com/stretchr/testify/assert" | ||
"golang.org/x/text/encoding/charmap" | ||
) | ||
|
||
type encodeNumberParameters struct { | ||
a byte | ||
b byte | ||
c byte | ||
d byte | ||
number int | ||
} | ||
|
||
type encodeStringParameters struct { | ||
decoded string | ||
encoded string | ||
} | ||
|
||
var encodeNumberTestCases []encodeNumberParameters | ||
var encodeStringTestCases []encodeStringParameters | ||
|
||
func TestMain(m *testing.M) { | ||
encodeNumberTestCases = []encodeNumberParameters{ | ||
{0x01, 0xFE, 0xFE, 0xFE, 0}, | ||
{0x02, 0xFE, 0xFE, 0xFE, 1}, | ||
{0x1D, 0xFE, 0xFE, 0xFE, 28}, | ||
{0x65, 0xFE, 0xFE, 0xFE, 100}, | ||
{0x81, 0xFE, 0xFE, 0xFE, 128}, | ||
{0xFD, 0xFE, 0xFE, 0xFE, 252}, | ||
{0x01, 0x02, 0xFE, 0xFE, 253}, | ||
{0x02, 0x02, 0xFE, 0xFE, 254}, | ||
{0x03, 0x02, 0xFE, 0xFE, 255}, | ||
{0x7E, 0x7F, 0xFE, 0xFE, 32003}, | ||
{0x7F, 0x7F, 0xFE, 0xFE, 32004}, | ||
{0x80, 0x7F, 0xFE, 0xFE, 32005}, | ||
{0xFD, 0xFD, 0xFE, 0xFE, 64008}, | ||
{0x01, 0x01, 0x02, 0xFE, 64009}, | ||
{0x02, 0x01, 0x02, 0xFE, 64010}, | ||
{0xB0, 0x3A, 0x9D, 0xFE, 10_000_000}, | ||
{0xFD, 0xFD, 0xFD, 0xFE, 16_194_276}, | ||
{0x01, 0x01, 0x01, 0x02, 16_194_277}, | ||
{0x02, 0x01, 0x01, 0x02, 16_194_278}, | ||
{0x7E, 0x7F, 0x7F, 0x7F, 2_048_576_039}, | ||
{0x7F, 0x7F, 0x7F, 0x7F, 2_048_576_040}, | ||
{0x80, 0x7F, 0x7F, 0x7F, 2_048_576_041}, | ||
{0xFC, 0xFD, 0xFD, 0xFD, int(4097152079)}, | ||
{0xFD, 0xFD, 0xFD, 0xFD, int(4097152080)}, | ||
} | ||
|
||
encodeStringTestCases = []encodeStringParameters{ | ||
{"Hello, World!", "!;a-^H s^3a:)"}, | ||
{"We're ¼ of the way there, so ¾ is remaining.", "C8_6_6l2h- ,d ¾ ^, sh-h7Y T>V h7Y g0 ¼ :[xhH"}, | ||
{"64² = 4096", ";fAk b ²=i"}, | ||
{"© FÒÖ BÃR BÅZ 2014", "=nAm EÅ] MÃ] ÖÒY ©"}, | ||
{"Öxxö Xööx \"Lëïth Säë\" - \"Ÿ\"", "OŸO D OëäL 7YïëSO UööG öU'Ö"}, | ||
{"Padded with 0xFFÿÿÿÿÿÿÿÿ", "ÿÿÿÿÿÿÿÿ+YUo 7Y6V i:i;lO"}, | ||
} | ||
|
||
os.Exit(m.Run()) | ||
} | ||
|
||
func TestEncodeNumber(t *testing.T) { | ||
for _, tc := range encodeNumberTestCases { | ||
t.Run(fmt.Sprintf("%d should encode to [%d, %d, %d, %d]", tc.number, tc.a, tc.b, tc.c, tc.d), | ||
func(t *testing.T) { | ||
actual := data.EncodeNumber(tc.number) | ||
assert.Equal(t, []byte{tc.a, tc.b, tc.c, tc.d}, actual) | ||
}) | ||
} | ||
} | ||
|
||
func TestDecodeNumber(t *testing.T) { | ||
for _, tc := range encodeNumberTestCases { | ||
t.Run(fmt.Sprintf("[%d, %d, %d, %d] should decode to %d", tc.a, tc.b, tc.c, tc.d, tc.number), | ||
func(t *testing.T) { | ||
actual := data.DecodeNumber([]byte{tc.a, tc.b, tc.c, tc.d}) | ||
assert.Equal(t, tc.number, actual) | ||
}) | ||
} | ||
} | ||
|
||
func TestEncodeString(t *testing.T) { | ||
for _, tc := range encodeStringTestCases { | ||
t.Run(fmt.Sprintf("%s should encode to %s", tc.decoded, tc.encoded), | ||
func(t *testing.T) { | ||
bytes := toBytes(tc.decoded) | ||
encoded := data.EncodeString(bytes) | ||
assert.Equal(t, toBytes(tc.encoded), encoded) | ||
}) | ||
} | ||
} | ||
|
||
func TestDecodeString(t *testing.T) { | ||
for _, tc := range encodeStringTestCases { | ||
t.Run(fmt.Sprintf("%s should decode to %s", tc.encoded, tc.decoded), | ||
func(t *testing.T) { | ||
bytes := toBytes(tc.encoded) | ||
decoded := data.DecodeString(bytes) | ||
assert.Equal(t, toBytes(tc.decoded), decoded) | ||
}) | ||
} | ||
} | ||
|
||
func toBytes(input string) (ret []byte) { | ||
for _, r := range input { | ||
next, _ := charmap.Windows1252.EncodeRune(r) | ||
ret = append(ret, next) | ||
} | ||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package data | ||
|
||
// Numeric maximum values for different EO data sizes | ||
const ( | ||
CHAR_MAX int = 253 // represents the maximum value of an EO char (1-byte encoded integer) | ||
SHORT_MAX int = CHAR_MAX * CHAR_MAX // represents the maximum value of an EO short (2-byte encoded integer) | ||
THREE_MAX int = CHAR_MAX * CHAR_MAX * CHAR_MAX // represents the maximum value of an EO three (3-byte encoded integer) | ||
INT_MAX int = SHORT_MAX * SHORT_MAX // represents the maximum value of an EO int (4-byte encoded integer) | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
// Packate data provides utilities to read and write EO data types. | ||
package data |
Oops, something went wrong.