Skip to content

Commit

Permalink
Merge pull request #4 from ropenttd/ottd14
Browse files Browse the repository at this point in the history
Support OpenTTD 14 admin interface changes (protocol 3)
  • Loading branch information
duckfullstop committed Apr 9, 2024
2 parents ccf1a51 + a037387 commit 2a6f2b9
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 59 deletions.
6 changes: 5 additions & 1 deletion cmd/openttd_adm_query/openttd_scrape.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"flag"
"fmt"
gopenttd "github.com/ropenttd/gopenttd/pkg/admin"
"github.com/ropenttd/gopenttd/pkg/admin/enum"
log "github.com/sirupsen/logrus"
"time"
)
Expand Down Expand Up @@ -39,8 +40,11 @@ func main() {
}
defer s.Close()

s.RequestUpdates(enum.UpdateTypeCompanyInfo, enum.UpdateFrequencyAutomatically)
s.RequestUpdates(enum.UpdateTypeCompanyEconomy, enum.UpdateFrequencyAutomatically)

// stupid delay to make sure things settle into state (? find a better way to do this)
time.Sleep(3 * time.Second)
time.Sleep(10 * time.Second)

state := s.State
var b []byte
Expand Down
71 changes: 50 additions & 21 deletions pkg/admin/packets/packets_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"github.com/ropenttd/gopenttd/pkg/admin/enum"
"io"
"reflect"
)

Expand All @@ -27,33 +28,61 @@ func genericUnmarshal(p AdminResponsePacket, buffer *bytes.Buffer) (err error) {
// binary.Read() doesn't appear to work here (always returns 0?) so do things the long way
// i.e binary.Read(buffer, binary.LittleEndian, nv)
case reflect.Bool:
var nv bool
nv = uint8(buffer.Next(1)[0]) != 0
f.Set(reflect.ValueOf(nv))
if buffer.Len() >= 1 {
var nv bool
nv = uint8(buffer.Next(1)[0]) != 0
f.Set(reflect.ValueOf(nv))
} else {
return io.ErrUnexpectedEOF
}
case reflect.Uint8:
var nv uint8
nv = uint8(buffer.Next(1)[0])
f.Set(reflect.ValueOf(nv))
if buffer.Len() >= 1 {
var nv uint8
nv = uint8(buffer.Next(1)[0])
f.Set(reflect.ValueOf(nv))
} else {
return io.ErrUnexpectedEOF
}
case reflect.Uint16:
var nv uint16
nv = binary.LittleEndian.Uint16(buffer.Next(2))
f.Set(reflect.ValueOf(nv))
if buffer.Len() >= 2 {
var nv uint16
nv = binary.LittleEndian.Uint16(buffer.Next(2))
f.Set(reflect.ValueOf(nv))
} else {
return io.ErrUnexpectedEOF
}
case reflect.Uint32:
var nv uint32
nv = binary.LittleEndian.Uint32(buffer.Next(4))
f.Set(reflect.ValueOf(nv))
if buffer.Len() >= 4 {
var nv uint32
nv = binary.LittleEndian.Uint32(buffer.Next(4))
f.Set(reflect.ValueOf(nv))
} else {
return io.ErrUnexpectedEOF
}
case reflect.Int64:
var nv int64
binary.Read(buffer, binary.LittleEndian, &nv)
f.Set(reflect.ValueOf(nv))
if buffer.Len() >= 8 {
var nv int64
binary.Read(buffer, binary.LittleEndian, &nv)
f.Set(reflect.ValueOf(nv))
} else {
return io.ErrUnexpectedEOF
}
case reflect.Uint64:
var nv uint64
nv = binary.LittleEndian.Uint64(buffer.Next(8))
f.Set(reflect.ValueOf(nv))
if buffer.Len() >= 8 {
var nv uint64
nv = binary.LittleEndian.Uint64(buffer.Next(8))
f.Set(reflect.ValueOf(nv))
} else {
return io.ErrUnexpectedEOF
}
case reflect.String:
nvBytes, _ := buffer.ReadBytes(byte(0))
nv := string(bytes.Trim(nvBytes, "\x00"))
f.Set(reflect.ValueOf(nv))
if buffer.Len() >= 1 {
nvBytes, _ := buffer.ReadBytes(byte(0))
nv := string(bytes.Trim(nvBytes, "\x00"))
f.Set(reflect.ValueOf(nv))
} else {
return io.ErrUnexpectedEOF
}
}
}
return err
Expand Down
83 changes: 50 additions & 33 deletions pkg/admin/proto_unmarshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,71 +34,88 @@ func ottdUnmarshalData(buffer *bytes.Buffer, val reflect.Value, set bool) (gen i
// i.e binary.Read(buffer, binary.LittleEndian, nv)
case reflect.Bool:
var nv bool
nv = uint8(buffer.Next(1)[0]) != 0
if set {
val.Set(reflect.ValueOf(nv))
if buffer.Len() >= 1 {
nv = uint8(buffer.Next(1)[0]) != 0
if set {
val.Set(reflect.ValueOf(nv))
}
}
return nv
case reflect.Uint8:
var nv uint8
nv = uint8(buffer.Next(1)[0])
if set {
val.Set(reflect.ValueOf(nv))
if buffer.Len() >= 1 {
nv = uint8(buffer.Next(1)[0])
if set {
val.Set(reflect.ValueOf(nv))
}
}
return nv
case reflect.Uint16:
var nv uint16
nv = binary.LittleEndian.Uint16(buffer.Next(2))
if set {
val.Set(reflect.ValueOf(nv))
if buffer.Len() >= 2 {
nv = binary.LittleEndian.Uint16(buffer.Next(2))
if set {
val.Set(reflect.ValueOf(nv))
}
}
return nv
case reflect.Uint32:
var nv uint32
nv = binary.LittleEndian.Uint32(buffer.Next(4))
if set {
val.Set(reflect.ValueOf(nv))
if buffer.Len() >= 1 {
nv = binary.LittleEndian.Uint32(buffer.Next(4))
if set {
val.Set(reflect.ValueOf(nv))
}
}
return nv
case reflect.Int64:
var nv int64
binary.Read(buffer, binary.LittleEndian, &nv)
if set {
val.Set(reflect.ValueOf(nv))
if buffer.Len() >= 64 {
binary.Read(buffer, binary.LittleEndian, &nv)
if set {
val.Set(reflect.ValueOf(nv))
}
}
return nv
case reflect.Uint64:
var nv uint64
nv = binary.LittleEndian.Uint64(buffer.Next(8))
if set {
val.Set(reflect.ValueOf(nv))
if buffer.Len() >= 64 {
nv = binary.LittleEndian.Uint64(buffer.Next(8))
if set {
val.Set(reflect.ValueOf(nv))
}
}
return nv
case reflect.String:
nvBytes, _ := buffer.ReadBytes(byte(0))
nv := string(bytes.Trim(nvBytes, "\x00"))
if set {
val.Set(reflect.ValueOf(nv))
var nv string
if buffer.Len() >= 1 {
nvBytes, _ := buffer.ReadBytes(byte(0))
nv = string(bytes.Trim(nvBytes, "\x00"))
if set {
val.Set(reflect.ValueOf(nv))
}
}
return nv
case reflect.Map:
// This is handled in a special, openttd way
val.Set(reflect.MakeMap(val.Type()))
var next bool
next = uint8(buffer.Next(1)[0]) != 0
for next {
// there are settings to read
// read the key data
k := reflect.Zero(val.Type().Key())
k = reflect.ValueOf(ottdUnmarshalData(buffer, k, false))
if buffer.Len() >= 1 {
next = uint8(buffer.Next(1)[0]) != 0
for next {
// there are settings to read
// read the key data
k := reflect.Zero(val.Type().Key())
k = reflect.ValueOf(ottdUnmarshalData(buffer, k, false))

// then read the value data
v := reflect.Zero(val.Type().Elem())
v = reflect.ValueOf(ottdUnmarshalData(buffer, v, false))
// then read the value data
v := reflect.Zero(val.Type().Elem())
v = reflect.ValueOf(ottdUnmarshalData(buffer, v, false))

val.SetMapIndex(k, v)
val.SetMapIndex(k, v)

next = uint8(buffer.Next(1)[0]) != 0
next = uint8(buffer.Next(1)[0]) != 0
}
}
return val
}
Expand Down
12 changes: 8 additions & 4 deletions pkg/admin/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,10 +306,14 @@ func (s *State) onCompanyUpdate(se *Session, r *CompanyUpdate) (err error) {
com.Colour = helpers.OpenttdColour(r.Colour)
com.Passworded = r.Password
com.Bankruptcy = r.BankruptcyQuarters
com.Share1 = r.Share1
com.Share2 = r.Share2
com.Share3 = r.Share3
com.Share4 = r.Share4

if se.State.ProtocolVersion <= 2 {
// Company shares were removed in OpenTTD 14.0.
com.Share1 = r.Share1
com.Share2 = r.Share2
com.Share3 = r.Share3
com.Share4 = r.Share4
}

s.Companies[r.ID] = com

Expand Down

0 comments on commit 2a6f2b9

Please sign in to comment.