mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-11-16 09:25:57 -05:00
Added stream writer and reader. Updated readme.
This commit is contained in:
parent
cb5c068279
commit
89a72c6f33
51
Common/StreamReader.go
Normal file
51
Common/StreamReader.go
Normal file
@ -0,0 +1,51 @@
|
||||
package Common
|
||||
|
||||
// StreamReader allows you to read data from a byte array in various formats
|
||||
type StreamReader struct {
|
||||
data []byte
|
||||
position uint64
|
||||
}
|
||||
|
||||
// CreateStreamReader creates an instance of the stream reader
|
||||
func CreateStreamReader(source []byte) *StreamReader {
|
||||
result := &StreamReader{
|
||||
data: source,
|
||||
position: 0,
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// GetPosition returns the current stream position
|
||||
func (v *StreamReader) GetPosition() uint64 {
|
||||
return v.position
|
||||
}
|
||||
|
||||
// GetSize returns the total size of the stream in bytes
|
||||
func (v *StreamReader) GetSize() uint64 {
|
||||
return uint64(len(v.data))
|
||||
}
|
||||
|
||||
// GetByte returns a byte from the stream
|
||||
func (v *StreamReader) GetByte() byte {
|
||||
result := v.data[v.position]
|
||||
v.position++
|
||||
return result
|
||||
}
|
||||
|
||||
// GetWord returns a uint16 word from the stream
|
||||
func (v *StreamReader) GetWord() uint16 {
|
||||
result := uint16(v.data[v.position])
|
||||
result += (uint16(v.data[v.position+1]) << 8)
|
||||
v.position += 2
|
||||
return result
|
||||
}
|
||||
|
||||
// GetDword returns a uint32 dword from the stream
|
||||
func (v *StreamReader) GetDword() uint32 {
|
||||
result := uint32(v.data[v.position])
|
||||
result += (uint32(v.data[v.position+1]) << 8)
|
||||
result += (uint32(v.data[v.position+2]) << 16)
|
||||
result += (uint32(v.data[v.position+3]) << 24)
|
||||
v.position += 4
|
||||
return result
|
||||
}
|
56
Common/StreamReader_test.go
Normal file
56
Common/StreamReader_test.go
Normal file
@ -0,0 +1,56 @@
|
||||
package Common
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStreamReaderByte(t *testing.T) {
|
||||
data := []byte{0x78, 0x56, 0x34, 0x12}
|
||||
sr := CreateStreamReader(data)
|
||||
if sr.GetPosition() != 0 {
|
||||
t.Fatal("StreamReader.GetPosition() did not start at 0")
|
||||
}
|
||||
if ss := sr.GetSize(); ss != 4 {
|
||||
t.Fatalf("StreamREader.GetSize() was expected to return %d, but returned %d instead", 4, ss)
|
||||
}
|
||||
for i := 0; i < len(data); i++ {
|
||||
ret := sr.GetByte()
|
||||
if ret != data[i] {
|
||||
t.Fatalf("StreamReader.GetDword() was expected to return %X, but returned %X instead", data[i], ret)
|
||||
}
|
||||
if pos := sr.GetPosition(); pos != uint64(i+1) {
|
||||
t.Fatalf("StreamReader.GetPosition() should be at %d, but was at %d instead", i, pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStreamReaderWord(t *testing.T) {
|
||||
data := []byte{0x78, 0x56, 0x34, 0x12}
|
||||
sr := CreateStreamReader(data)
|
||||
ret := sr.GetWord()
|
||||
if ret != 0x5678 {
|
||||
t.Fatalf("StreamReader.GetDword() was expected to return %X, but returned %X instead", 0x5678, ret)
|
||||
}
|
||||
if pos := sr.GetPosition(); pos != 2 {
|
||||
t.Fatalf("StreamReader.GetPosition() should be at %d, but was at %d instead", 2, pos)
|
||||
}
|
||||
ret = sr.GetWord()
|
||||
if ret != 0x1234 {
|
||||
t.Fatalf("StreamReader.GetDword() was expected to return %X, but returned %X instead", 0x1234, ret)
|
||||
}
|
||||
if pos := sr.GetPosition(); pos != 4 {
|
||||
t.Fatalf("StreamReader.GetPosition() should be at %d, but was at %d instead", 4, pos)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStreamReaderDword(t *testing.T) {
|
||||
data := []byte{0x78, 0x56, 0x34, 0x12}
|
||||
sr := CreateStreamReader(data)
|
||||
ret := sr.GetDword()
|
||||
if ret != 0x12345678 {
|
||||
t.Fatalf("StreamReader.GetDword() was expected to return %X, but returned %X instead", 0x12345678, ret)
|
||||
}
|
||||
if pos := sr.GetPosition(); pos != 4 {
|
||||
t.Fatalf("StreamReader.GetPosition() should be at %d, but was at %d instead", 4, pos)
|
||||
}
|
||||
}
|
37
Common/StreamWriter.go
Normal file
37
Common/StreamWriter.go
Normal file
@ -0,0 +1,37 @@
|
||||
package Common
|
||||
|
||||
// StreamWriter allows you to create a byte array by streaming in writes of various sizes
|
||||
type StreamWriter struct {
|
||||
data []byte
|
||||
}
|
||||
|
||||
// CreateStreamWriter creates a new StreamWriter instance
|
||||
func CreateStreamWriter() *StreamWriter {
|
||||
result := &StreamWriter{
|
||||
data: make([]byte, 0),
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// PushByte writes a byte to the stream
|
||||
func (v *StreamWriter) PushByte(val byte) {
|
||||
v.data = append(v.data, val)
|
||||
}
|
||||
|
||||
// PushWord writes an uint16 word to the stream
|
||||
func (v *StreamWriter) PushWord(val uint16) {
|
||||
v.data = append(v.data, byte(val&0xFF))
|
||||
v.data = append(v.data, byte((val>>8)&0xFF))
|
||||
}
|
||||
|
||||
// PushDword writes a uint32 dword to the stream
|
||||
func (v *StreamWriter) PushDword(val uint32) {
|
||||
v.data = append(v.data, byte(val&0xFF))
|
||||
v.data = append(v.data, byte((val>>8)&0xFF))
|
||||
v.data = append(v.data, byte((val>>16)&0xFF))
|
||||
v.data = append(v.data, byte((val>>24)&0xFF))
|
||||
}
|
||||
|
||||
func (v *StreamWriter) GetBytes() []byte {
|
||||
return v.data
|
||||
}
|
44
Common/StreamWriter_test.go
Normal file
44
Common/StreamWriter_test.go
Normal file
@ -0,0 +1,44 @@
|
||||
package Common
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStreamWriterByte(t *testing.T) {
|
||||
sr := CreateStreamWriter()
|
||||
data := []byte{0x12, 0x34, 0x56, 0x78}
|
||||
for _, d := range data {
|
||||
sr.PushByte(d)
|
||||
}
|
||||
output := sr.GetBytes()
|
||||
for i, d := range data {
|
||||
if output[i] != d {
|
||||
t.Fatalf("sr.PushByte() pushed %X, but wrote %X instead", d, output[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStreamWriterWord(t *testing.T) {
|
||||
sr := CreateStreamWriter()
|
||||
data := []byte{0x12, 0x34, 0x56, 0x78}
|
||||
sr.PushWord(0x3412)
|
||||
sr.PushWord(0x7856)
|
||||
output := sr.GetBytes()
|
||||
for i, d := range data {
|
||||
if output[i] != d {
|
||||
t.Fatalf("sr.PushWord() pushed byte %X to %d, but %X was expected instead", output[i], i, d)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStreamWriterDword(t *testing.T) {
|
||||
sr := CreateStreamWriter()
|
||||
data := []byte{0x12, 0x34, 0x56, 0x78}
|
||||
sr.PushDword(0x78563412)
|
||||
output := sr.GetBytes()
|
||||
for i, d := range data {
|
||||
if output[i] != d {
|
||||
t.Fatalf("sr.PushDword() pushed byte %X to %d, but %X was expected instead", output[i], i, d)
|
||||
}
|
||||
}
|
||||
}
|
32
README.md
32
README.md
@ -29,9 +29,39 @@ To run the project, run `go run ./cmd/Client` from the root folder.
|
||||
|
||||
You can also open the root folder in VSCode. Make sure you have the `ms-vscode.go` plugin installed.
|
||||
|
||||
## VS Code Extensions
|
||||
|
||||
The following extensions are recommended for working with this project:
|
||||
* ms-vscode.go
|
||||
* defaltd.go-coverage-viewer
|
||||
|
||||
For the Go extension, it is recommended you add the following to settings.json:
|
||||
```json
|
||||
"go.languageServerExperimentalFeatures": {
|
||||
"format": true,
|
||||
"autoComplete": true,
|
||||
"rename": true,
|
||||
"goToDefinition": true,
|
||||
"hover": true,
|
||||
"signatureHelp": true,
|
||||
"goToTypeDefinition": true,
|
||||
"goToImplementation": true,
|
||||
"documentSymbols": true,
|
||||
"workspaceSymbols": true,
|
||||
"findReferences": true,
|
||||
"diagnostics": true,
|
||||
"documentLink": true
|
||||
},
|
||||
```
|
||||
|
||||
You can get to it by going to settings <kbd>Ctrl+,</kbd>, expanding `Extensions` and selecting `Go configuration`,
|
||||
then clicking on `Edit in settings.json`. Just paste that section where appropriate.
|
||||
|
||||
## Configuration
|
||||
|
||||
The engine is configured via the `config.json` file.
|
||||
The engine is configured via the `config.json` file. By default, the configuration assumes that you have installed Diablo 2 and the
|
||||
expansion via the official Blizzard Diablo2 installers using the default file paths. If you are not on Windows, or have installed
|
||||
the game in a different location, the base path may have to be adjusted.
|
||||
|
||||
|
||||
## Contributing
|
||||
|
Loading…
Reference in New Issue
Block a user