forked from phumberdroz/irsdk-go
/
sdk.go
123 lines (111 loc) · 2.62 KB
/
sdk.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package sdk
import (
"fmt"
"io"
"sync"
"time"
"bitbucket.org/avd/go-ipc/mmf"
"github.com/0xkalle/irsdk-go/internal/shm"
"github.com/0xkalle/irsdk-go/pkg/session"
"golang.org/x/text/encoding/charmap"
)
type reader interface {
io.Reader
io.ReaderAt
//io.Closer
}
type SDK struct {
r reader
Header Header
s session.SessionData
TelemetryVars TelemetryVars
lastValidData int64
Timeout time.Duration
}
type TelemetryVars struct {
lastVersion int32
Vars map[string]Variable
mux sync.Mutex
}
type Variable struct {
VarType int32 // irsdk_VarType
Offset int32 // Offset fron start of buffer row
Count int32 // number of entrys (array) so length in bytes would be irsdk_VarTypeBytes[type] * Count
CountAsTime bool
Name string
Desc string
Unit string
Value interface{}
rawBytes []byte
}
const fileMapName string = "Local\\IRSDKMemMapFileName"
const fileMapSize int = 1164 * 1024
func InitSdk(r reader) (SDK, error) {
if r == nil {
object, err := shm.NewWindowsNativeMemoryObject(fileMapName, 0, fileMapSize)
if err != nil {
return SDK{}, err
}
roRegion, err := mmf.NewMemoryRegion(object, mmf.MEM_READ_ONLY, 0, fileMapSize)
if err != nil {
return SDK{}, err
}
regionReader := mmf.NewMemoryRegionReader(roRegion)
r = regionReader
}
/*
Todo consider sending event
https://github.com/vipoo/irsdk/blob/a14be906d1a6198aa0c6423022ed5246f20be3bb/irsdk_utils.cpp#L87-L101
*/
sdk := SDK{
r: r,
lastValidData: 0,
Timeout: 30 * time.Second,
}
h, err := readHeader(sdk.r)
if err != nil {
return SDK{}, err
}
sdk.Header = h
//if sdk.tVars != nil {
// sdk.tVars.vars = nil
//}
if !sdk.SessionStatusOK() {
return SDK{}, fmt.Errorf("session status is not okay")
}
sdk.TelemetryVars = readVariableHeaders(sdk.r, &sdk.Header)
sdk.ReadVariableValues()
return sdk, nil
}
func (s SDK) ReadHeader() (Header, error) {
if s.r == nil {
return Header{}, fmt.Errorf("reader not initialized")
}
return readHeader(s.r)
}
func (s SDK) GetSessionData() ([]byte, error) {
if !s.SessionStatusOK() {
return nil, fmt.Errorf("session Status not ok")
}
rbuf := make([]byte, s.Header.SessionInfoLen)
_, err := s.r.ReadAt(rbuf, int64(s.Header.SessionInfoOffset))
if err != nil {
return nil, err
}
dec := charmap.Windows1258.NewDecoder()
rbuf, err = dec.Bytes(rbuf)
if err != nil {
return nil, err
}
var r []byte
for _, b := range rbuf {
if b != byte(0) {
r = append(r, b)
}
}
return r, nil
//return rbuf[:len(rbuf)], nil
}
func (s SDK) SessionStatusOK() bool {
return s.Header.Status > 0
}