This repository has been archived by the owner on Jan 22, 2024. It is now read-only.
forked from direct-connect/go-dc
/
ping.go
162 lines (146 loc) · 3.07 KB
/
ping.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
package nmdc
import (
"bytes"
"errors"
"strconv"
"strings"
"github.com/aler9/go-dc/types"
)
func init() {
RegisterMessage(&BotINFO{})
RegisterMessage(&HubINFO{})
}
// BotINFO is sent by the pinger to the hub to get a HubINFO.
type BotINFO struct {
String
}
func (*BotINFO) Type() string {
return "BotINFO"
}
// HubINFO is a detailed hub information exposed only after receiving BotINFO.
type HubINFO struct {
Name string
Host string
Desc string
I1 int // TODO
I2 int // TODO
I3 int // TODO
I4 int // TODO
Soft types.Software
Owner string
State string // TODO
Encoding string
}
func (*HubINFO) Type() string {
return "HubINFO"
}
func (m *HubINFO) MarshalNMDC(enc *TextEncoder, buf *bytes.Buffer) error {
const sep = '$'
if err := String(m.Name).MarshalNMDC(enc, buf); err != nil {
return err
}
buf.WriteByte(sep)
buf.WriteString(m.Host)
buf.WriteByte(sep)
if err := String(m.Desc).MarshalNMDC(enc, buf); err != nil {
return err
}
buf.WriteByte(sep)
buf.WriteString(strconv.Itoa(m.I1))
buf.WriteByte(sep)
buf.WriteString(strconv.Itoa(m.I2))
buf.WriteByte(sep)
buf.WriteString(strconv.Itoa(m.I3))
buf.WriteByte(sep)
buf.WriteString(strconv.Itoa(m.I4))
buf.WriteByte(sep)
if m.Soft.Version == "" {
buf.WriteString(m.Soft.Name)
} else {
buf.WriteString(m.Soft.Name)
buf.WriteByte(' ')
buf.WriteString(m.Soft.Version)
}
buf.WriteByte(sep)
if err := String(m.Owner).MarshalNMDC(enc, buf); err != nil {
return err
}
buf.WriteByte(sep)
if err := String(m.State).MarshalNMDC(enc, buf); err != nil {
return err
}
buf.WriteByte(sep)
buf.WriteString(m.Encoding)
return nil
}
func (m *HubINFO) UnmarshalNMDC(dec *TextDecoder, data []byte) error {
fields := bytes.SplitN(data, []byte("$"), 13)
for i, field := range fields {
switch i {
case 0:
var s String
if err := s.UnmarshalNMDC(dec, field); err != nil {
return err
}
m.Name = string(s)
case 1:
m.Host = string(field)
case 2:
var s String
if err := s.UnmarshalNMDC(dec, field); err != nil {
return err
}
m.Desc = string(s)
case 3:
i1, err := atoiTrim(field)
if err != nil {
return errors.New("invalid i1")
}
m.I1 = i1
case 4:
i2, err := atoiTrim(field)
if err != nil {
return errors.New("invalid i2")
}
m.I2 = i2
case 5:
i3, err := atoiTrim(field)
if err != nil {
return errors.New("invalid i3")
}
m.I3 = i3
case 6:
i4, err := atoiTrim(field)
if err != nil {
return errors.New("invalid i4")
}
m.I4 = i4
case 7:
soft := string(field)
m.Soft.Name = soft
if i := strings.LastIndexByte(soft, ' '); i >= 0 {
m.Soft.Name = soft[:i]
m.Soft.Version = soft[i+1:]
}
case 8:
var s String
if err := s.UnmarshalNMDC(dec, field); err != nil {
return err
}
m.Owner = string(s)
case 9:
var s String
if err := s.UnmarshalNMDC(dec, field); err != nil {
return err
}
m.State = string(s)
case 10:
if len(fields) < 12 {
m.Encoding = string(field)
}
default:
// ignore everything else
}
}
return nil
}