-
Notifications
You must be signed in to change notification settings - Fork 8
/
gns.go
1878 lines (1664 loc) · 94.4 KB
/
gns.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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// Author: Niels A.D.
// Project: gamenetworkingsockets (https://github.com/nielsAD/gns)
// License: Mozilla Public License, v2.0
// Package gns provides golang bindings for the GameNetworkingSockets library.
package gns
import (
"encoding/binary"
"errors"
"fmt"
"net"
"sync/atomic"
"time"
"unsafe"
)
// #cgo !gns_static LDFLAGS: -lGameNetworkingSockets -L${SRCDIR}/lib/GameNetworkingSockets/build/src
// #cgo gns_static,!windows LDFLAGS: -lGameNetworkingSockets_s -lssl -lcrypto -lprotobuf -L${SRCDIR}/lib/GameNetworkingSockets/build/src
// #cgo gns_static,windows LDFLAGS: -lGameNetworkingSockets_s -lssl -lcrypto -lprotobuf -lws2_32 -L${SRCDIR}/lib/GameNetworkingSockets/build/src
/*
#include <gns.h>
static inline SteamNetConnectionInfo_t *StatusChangedCallbackInfo_GetInfo(SteamNetConnectionStatusChangedCallback_t *cb) {
return &cb->m_info;
}
void goDebugOutputCallback(ESteamNetworkingSocketsDebugOutputType nType, char *pszMsg);
void goStatusChangedCallback(SteamNetConnectionStatusChangedCallback_t *pInfo, intptr_t context);
*/
import "C"
// DebugOutputType is the interface to ESteamNetworkingSocketsDebugOutputType
//
// Detail level for diagnostic output callback.
// See ISteamNetworkingUtils::SetDebugOutputFunction
type DebugOutputType C.ESteamNetworkingSocketsDebugOutputType
// DebugOutputType constants
const (
DebugOutputTypeNone = C.k_ESteamNetworkingSocketsDebugOutputType_None
DebugOutputTypeBug = C.k_ESteamNetworkingSocketsDebugOutputType_Bug // You used the API incorrectly, or an internal error happened
DebugOutputTypeError = C.k_ESteamNetworkingSocketsDebugOutputType_Error // Run-time error condition that isn't the result of a bug. (E.g. we are offline, cannot bind a port, etc)
DebugOutputTypeImportant = C.k_ESteamNetworkingSocketsDebugOutputType_Important // Nothing is wrong, but this is an important notification
DebugOutputTypeWarning = C.k_ESteamNetworkingSocketsDebugOutputType_Warning
DebugOutputTypeMsg = C.k_ESteamNetworkingSocketsDebugOutputType_Msg // Recommended amount
DebugOutputTypeVerbose = C.k_ESteamNetworkingSocketsDebugOutputType_Verbose // Quite a bit
DebugOutputTypeDebug = C.k_ESteamNetworkingSocketsDebugOutputType_Debug // Practically everything
DebugOutputTypeEverything = C.k_ESteamNetworkingSocketsDebugOutputType_Everything // Wall of text, detailed packet contents breakdown, etc
)
// DebugOutputFunc used for debug callback
type DebugOutputFunc func(typ DebugOutputType, msg string)
var debugOutputCallback DebugOutputFunc
//export goDebugOutputCallback
func goDebugOutputCallback(nType C.ESteamNetworkingSocketsDebugOutputType, pszMsg *C.char) {
typ := (DebugOutputType)(nType)
msg := C.GoString(pszMsg)
debugOutputCallback(typ, msg)
}
// StatusChangedCallbackInfo is the interface to SteamNetConnectionStatusChangedCallback_t
type StatusChangedCallbackInfo = C.SteamNetConnectionStatusChangedCallback_t
// Conn returns m_hConn
func (cb *StatusChangedCallbackInfo) Conn() Connection {
return (Connection)(cb.m_hConn)
}
// Info returns m_info
func (cb *StatusChangedCallbackInfo) Info() *ConnectionInfo {
return C.StatusChangedCallbackInfo_GetInfo(cb)
}
// OldState returns m_eOldState
func (cb *StatusChangedCallbackInfo) OldState() ConnectionState {
return (ConnectionState)(cb.m_eOldState)
}
// StatusChangedCallback function
type StatusChangedCallback func(info *StatusChangedCallbackInfo)
// internal temporary callback function storage
var statusChangedCallbacks [256]StatusChangedCallback
//export goStatusChangedCallback
func goStatusChangedCallback(pInfo *StatusChangedCallbackInfo, context C.intptr_t) {
statusChangedCallbacks[(int)(context)](pInfo)
}
// ListenSocket is the interface to HSteamListenSocket
//
// Handle used to identify a "listen socket". Unlike traditional
// Berkeley sockets, a listen socket and a connection are two
// different abstractions.
type ListenSocket C.HSteamListenSocket
// InvalidListenSocket constant
const InvalidListenSocket ListenSocket = C.k_HSteamListenSocket_Invalid
// Connection is the interface to HSteamNetConnection
//
// Handle used to identify a connection to a remote host.
type Connection C.HSteamNetConnection
// InvalidConnection constant
const InvalidConnection Connection = C.k_HSteamNetConnection_Invalid
// PollGroup is the interface to HSteamNetPollGroup
//
// Handle used to identify a poll group, used to query many
// connections at once efficiently.
type PollGroup C.HSteamNetPollGroup
// InvalidPollGroup constant
const InvalidPollGroup PollGroup = C.k_HSteamNetPollGroup_Invalid
// Timestamp is the interface to SteamNetworkingMicroseconds
//
// A local timestamp. You can subtract two timestamps to get the number of elapsed
// microseconds. This is guaranteed to increase over time during the lifetime
// of a process, but not globally across runs. You don't need to worry about
// the value wrapping around. Note that the underlying clock might not actually have
// microsecond resolution.
type Timestamp C.SteamNetworkingMicroseconds
// ConfigOption is the interface to ESteamNetworkingConfigValue
type ConfigOption C.ESteamNetworkingConfigValue
// ConfigOption constants
const (
ConfigInvalid ConfigOption = C.k_ESteamNetworkingConfig_Invalid
// [global float, 0--100] Randomly discard N pct of packets instead of sending/recv
// This is a global option only, since it is applied at a low level
// where we don't have much context
ConfigFakePacketLossSend ConfigOption = C.k_ESteamNetworkingConfig_FakePacketLoss_Send
ConfigFakePacketLossRecv ConfigOption = C.k_ESteamNetworkingConfig_FakePacketLoss_Recv
// [global int32]. Delay all outbound/inbound packets by N ms
ConfigFakePacketLagSend ConfigOption = C.k_ESteamNetworkingConfig_FakePacketLag_Send
ConfigFakePacketLagRecv ConfigOption = C.k_ESteamNetworkingConfig_FakePacketLag_Recv
// [global float] 0-100 Percentage of packets we will add additional delay
// to (causing them to be reordered)
ConfigFakePacketReorderSend ConfigOption = C.k_ESteamNetworkingConfig_FakePacketReorder_Send
ConfigFakePacketReorderRecv ConfigOption = C.k_ESteamNetworkingConfig_FakePacketReorder_Recv
// [global int32] Extra delay, in ms, to apply to reordered packets.
ConfigFakePacketReorderTime ConfigOption = C.k_ESteamNetworkingConfig_FakePacketReorder_Time
// [global float 0--100] Globally duplicate some percentage of packets we send
ConfigFakePacketDupSend ConfigOption = C.k_ESteamNetworkingConfig_FakePacketDup_Send
ConfigFakePacketDupRecv ConfigOption = C.k_ESteamNetworkingConfig_FakePacketDup_Recv
// [global int32] Amount of delay, in ms, to delay duplicated packets.
// (We chose a random delay between 0 and this value)
ConfigFakePacketDupTimeMax ConfigOption = C.k_ESteamNetworkingConfig_FakePacketDup_TimeMax
// [connection int32] Timeout value (in ms) to use when first connecting
ConfigTimeoutInitial ConfigOption = C.k_ESteamNetworkingConfig_TimeoutInitial
// [connection int32] Timeout value (in ms) to use after connection is established
ConfigTimeoutConnected ConfigOption = C.k_ESteamNetworkingConfig_TimeoutConnected
// [connection int32] Upper limit of buffered pending bytes to be sent
// if this is reached SendMessage will return k_EResultLimitExceeded
// Default is 512k (524288 bytes)
ConfigSendBufferSize ConfigOption = C.k_ESteamNetworkingConfig_SendBufferSize
// [connection int32] Minimum/maximum send rate clamp, 0 is no limit.
// This value will control the min/max allowed sending rate that
// bandwidth estimation is allowed to reach. Default is 0 (no-limit)
ConfigSendRateMin ConfigOption = C.k_ESteamNetworkingConfig_SendRateMin
ConfigSendRateMax ConfigOption = C.k_ESteamNetworkingConfig_SendRateMax
// [connection int32] Nagle time, in microseconds. When SendMessage is called, if
// the outgoing message is less than the size of the MTU, it will be
// queued for a delay equal to the Nagle timer value. This is to ensure
// that if the application sends several small messages rapidly, they are
// coalesced into a single packet.
// See historical RFC 896. Value is in microseconds.
// Default is 5000us (5ms).
ConfigNagleTime ConfigOption = C.k_ESteamNetworkingConfig_NagleTime
// [connection int32] Don't automatically fail IP connections that don't have
// strong auth. On clients, this means we will attempt the connection even if
// we don't know our identity or can't get a cert. On the server, it means that
// we won't automatically reject a connection due to a failure to authenticate.
// (You can examine the incoming connection and decide whether to accept it.)
//
// This is a dev configuration value, and you should not let users modify it in
// production.
ConfigIPAllowWithoutAuth ConfigOption = C.k_ESteamNetworkingConfig_IP_AllowWithoutAuth
// [connection int32] Do not send UDP packets with a payload of
// larger than N bytes. If you set this, k_ESteamNetworkingConfig_MTU_DataSize
// is automatically adjusted
ConfigMTUPacketSize ConfigOption = C.k_ESteamNetworkingConfig_MTU_PacketSize
// [connection int32] (read only) Maximum message size you can send that
// will not fragment, based on k_ESteamNetworkingConfig_MTU_PacketSize
ConfigMTUDataSize ConfigOption = C.k_ESteamNetworkingConfig_MTU_DataSize
// [connection int32] Allow unencrypted (and unauthenticated) communication.
// 0: Not allowed (the default)
// 1: Allowed, but prefer encrypted
// 2: Allowed, and preferred
// 3: Required. (Fail the connection if the peer requires encryption.)
//
// This is a dev configuration value, since its purpose is to disable encryption.
// You should not let users modify it in production. (But note that it requires
// the peer to also modify their value in order for encryption to be disabled.)
ConfigUnencrypted ConfigOption = C.k_ESteamNetworkingConfig_Unencrypted
// [global int32] 0 or 1. Some variables are "dev" variables. They are useful
// for debugging, but should not be adjusted in production. When this flag is false (the default)
// such variables will not be enumerated by the ISteamnetworkingUtils::GetFirstConfigValue
// ISteamNetworkingUtils::GetConfigValueInfo functions. The idea here is that you
// can use those functions to provide a generic mechanism to set any configuration
// value from a console or configuration file, looking up the variable by name. Depending
// on your game, modifying other configuration values may also have negative effects, and
// you may wish to further lock down which variables are allowed to be modified by the user.
// (Maybe no variables!) Or maybe you use a whitelist or blacklist approach.
//
// (This flag is itself a dev variable.)
ConfigEnumerateDevVars ConfigOption = C.k_ESteamNetworkingConfig_EnumerateDevVars
//
// Log levels for debuging information. A higher priority
// (lower numeric value) will cause more stuff to be printed.
//
ConfigLogLevelAckRTT ConfigOption = C.k_ESteamNetworkingConfig_LogLevel_AckRTT // [connection int32] RTT calculations for inline pings and replies
ConfigLogLevelPacketDecode ConfigOption = C.k_ESteamNetworkingConfig_LogLevel_PacketDecode // [connection int32] log SNP packets send
ConfigLogLevelMessage ConfigOption = C.k_ESteamNetworkingConfig_LogLevel_Message // [connection int32] log each message send/recv
ConfigLogLevelPacketGaps ConfigOption = C.k_ESteamNetworkingConfig_LogLevel_PacketGaps // [connection int32] dropped packets
ConfigLogLevelP2PRendezvous ConfigOption = C.k_ESteamNetworkingConfig_LogLevel_P2PRendezvous // [connection int32] P2P rendezvous messages
)
// ConfigType is the interface to ESteamNetworkingConfigDataType
type ConfigType C.ESteamNetworkingConfigDataType
// ConfigType constants
const (
ConfigTypeInt32 ConfigType = C.k_ESteamNetworkingConfig_Int32
ConfigTypeInt64 ConfigType = C.k_ESteamNetworkingConfig_Int64
ConfigTypeFloat ConfigType = C.k_ESteamNetworkingConfig_Float
ConfigTypeString ConfigType = C.k_ESteamNetworkingConfig_String
ConfigTypeFunctionPtr ConfigType = C.k_ESteamNetworkingConfig_FunctionPtr // NOTE: When setting callbacks, you should put the pointer into a variable and pass a pointer to that variable.
)
// ConfigValue is the interface to SteamNetworkingConfigValue_t
//
// In a few places we need to set configuration options on listen sockets and connections, and
// have them take effect *before* the listen socket or connection really starts doing anything.
// Creating the object and then setting the options "immediately" after creation doesn't work
// completely, because network packets could be received between the time the object is created and
// when the options are applied. To set options at creation time in a reliable way, they must be
// passed to the creation function. This structure is used to pass those options.
//
// For the meaning of these fields, see ISteamNetworkingUtils::SetConfigValue. Basically
// when the object is created, we just iterate over the list of options and call
// ISteamNetworkingUtils::SetConfigValueStruct, where the scope arguments are supplied by the
// object being created.
type ConfigValue = C.SteamNetworkingConfigValue_t
// NewConfigValue maps interface{} to ConfigValue
func NewConfigValue(opt ConfigOption, val interface{}) *ConfigValue {
var res ConfigValue
res.m_eValue = C.ESteamNetworkingConfigValue(opt)
switch v := val.(type) {
case int:
res.m_eDataType = (C.ESteamNetworkingConfigDataType)(ConfigTypeInt32)
*(*C.int32_t)(unsafe.Pointer(&res.m_val)) = C.int32_t(v)
case int32:
res.m_eDataType = (C.ESteamNetworkingConfigDataType)(ConfigTypeInt32)
*(*C.int32_t)(unsafe.Pointer(&res.m_val)) = C.int32_t(v)
case int64:
res.m_eDataType = (C.ESteamNetworkingConfigDataType)(ConfigTypeInt64)
*(*C.int64_t)(unsafe.Pointer(&res.m_val)) = C.int64_t(v)
case float32:
res.m_eDataType = (C.ESteamNetworkingConfigDataType)(ConfigTypeFloat)
*(*C.float)(unsafe.Pointer(&res.m_val)) = C.float(v)
case float64:
res.m_eDataType = (C.ESteamNetworkingConfigDataType)(ConfigTypeFloat)
*(*C.float)(unsafe.Pointer(&res.m_val)) = C.float(v)
default:
panic("gns: Unsupported ConfigValue type")
}
return &res
}
// Val return go type
func (cfg *ConfigValue) Val() interface{} {
switch cfg.Type() {
case ConfigTypeInt32:
return cfg.Int32()
case ConfigTypeInt64:
return cfg.Int64()
case ConfigTypeFloat:
return cfg.Float()
case ConfigTypeString:
return cfg.String()
default:
panic("gns: Unsupported ConfigValue type")
}
}
// Type returns m_eDataType
func (cfg *ConfigValue) Type() ConfigType { return (ConfigType)(cfg.m_eDataType) }
// Int32 returns m_int32
func (cfg *ConfigValue) Int32() int32 { return int32(*(*C.int32_t)(unsafe.Pointer(&cfg.m_val))) }
// Int64 returns m_int64
func (cfg *ConfigValue) Int64() int64 { return int64(*(*C.int64_t)(unsafe.Pointer(&cfg.m_val))) }
// Float returns m_float
func (cfg *ConfigValue) Float() float32 { return float32(*(*C.float)(unsafe.Pointer(&cfg.m_val))) }
// Strings returns m_string
func (cfg *ConfigValue) String() string { return C.GoString((*C.char)(unsafe.Pointer(&cfg.m_val))) }
// ConfigMap convencience type
type ConfigMap map[ConfigOption]interface{}
func (m ConfigMap) pack() []C.SteamNetworkingConfigValue_t {
var res []C.SteamNetworkingConfigValue_t
for k, v := range m {
val := NewConfigValue(k, v)
res = append(res, (C.SteamNetworkingConfigValue_t)(*val))
}
return res
}
// Result is the interface to EResult
type Result C.EResult
func (r Result) Error() string {
switch r {
case ResultInvalidParam:
return "gns: EResultInvalidParam"
case ResultInvalidState:
return "gns: EResultInvalidState"
case ResultNoConnection:
return "gns: EResultNoConnection"
case ResultIgnored:
return "gns: EResultIgnored"
case ResultLimitExceeded:
return "gns: EResultLimitExceeded"
default:
return fmt.Sprintf("gns: EResult[%d]", int(r))
}
}
// Result constants
const (
ResultOK Result = C.k_EResultOK // success
ResultFail Result = C.k_EResultFail // generic failure
ResultNoConnection Result = C.k_EResultNoConnection // no/failed network connection
ResultInvalidPassword Result = C.k_EResultInvalidPassword // password/ticket is invalid
ResultLoggedInElsewhere Result = C.k_EResultLoggedInElsewhere // same user logged in elsewhere
ResultInvalidProtocolVer Result = C.k_EResultInvalidProtocolVer // protocol version is incorrect
ResultInvalidParam Result = C.k_EResultInvalidParam // a parameter is incorrect
ResultFileNotFound Result = C.k_EResultFileNotFound // file was not found
ResultBusy Result = C.k_EResultBusy // called method busy - action not taken
ResultInvalidState Result = C.k_EResultInvalidState // called object was in an invalid state
ResultInvalidName Result = C.k_EResultInvalidName // name is invalid
ResultInvalidEmail Result = C.k_EResultInvalidEmail // email is invalid
ResultDuplicateName Result = C.k_EResultDuplicateName // name is not unique
ResultAccessDenied Result = C.k_EResultAccessDenied // access is denied
ResultTimeout Result = C.k_EResultTimeout // operation timed out
ResultBanned Result = C.k_EResultBanned // VAC2 banned
ResultAccountNotFound Result = C.k_EResultAccountNotFound // account not found
ResultInvalidSteamID Result = C.k_EResultInvalidSteamID // steamID is invalid
ResultServiceUnavailable Result = C.k_EResultServiceUnavailable // The requested service is currently unavailable
ResultNotLoggedOn Result = C.k_EResultNotLoggedOn // The user is not logged on
ResultPending Result = C.k_EResultPending // Request is pending (may be in process, or waiting on third party)
ResultEncryptionFailure Result = C.k_EResultEncryptionFailure // Encryption or Decryption failed
ResultInsufficientPrivilege Result = C.k_EResultInsufficientPrivilege // Insufficient privilege
ResultLimitExceeded Result = C.k_EResultLimitExceeded // Too much of a good thing
ResultRevoked Result = C.k_EResultRevoked // Access has been revoked (used for revoked guest passes)
ResultExpired Result = C.k_EResultExpired // License/Guest pass the user is trying to access is expired
ResultAlreadyRedeemed Result = C.k_EResultAlreadyRedeemed // Guest pass has already been redeemed by account, cannot be acked again
ResultDuplicateRequest Result = C.k_EResultDuplicateRequest // The request is a duplicate and the action has already occurred in the past, ignored this time
ResultAlreadyOwned Result = C.k_EResultAlreadyOwned // All the games in this guest pass redemption request are already owned by the user
ResultIPNotFound Result = C.k_EResultIPNotFound // IP address not found
ResultPersistFailed Result = C.k_EResultPersistFailed // failed to write change to the data store
ResultLockingFailed Result = C.k_EResultLockingFailed // failed to acquire access lock for this operation
ResultLogonSessionReplaced Result = C.k_EResultLogonSessionReplaced
ResultConnectFailed Result = C.k_EResultConnectFailed
ResultHandshakeFailed Result = C.k_EResultHandshakeFailed
ResultIOFailure Result = C.k_EResultIOFailure
ResultRemoteDisconnect Result = C.k_EResultRemoteDisconnect
ResultShoppingCartNotFound Result = C.k_EResultShoppingCartNotFound // failed to find the shopping cart requested
ResultBlocked Result = C.k_EResultBlocked // a user didn't allow it
ResultIgnored Result = C.k_EResultIgnored // target is ignoring sender
ResultNoMatch Result = C.k_EResultNoMatch // nothing matching the request found
ResultAccountDisabled Result = C.k_EResultAccountDisabled
ResultServiceReadOnly Result = C.k_EResultServiceReadOnly // this service is not accepting content changes right now
ResultAccountNotFeatured Result = C.k_EResultAccountNotFeatured // account doesn't have value, so this feature isn't available
ResultAdministratorOK Result = C.k_EResultAdministratorOK // allowed to take this action, but only because requester is admin
ResultContentVersion Result = C.k_EResultContentVersion // A Version mismatch in content transmitted within the Steam protocol.
ResultTryAnotherCM Result = C.k_EResultTryAnotherCM // The current CM can't service the user making a request, user should try another.
ResultPasswordRequiredToKickSession Result = C.k_EResultPasswordRequiredToKickSession // You are already logged in elsewhere, this cached credential login has failed.
ResultAlreadyLoggedInElsewhere Result = C.k_EResultAlreadyLoggedInElsewhere // You are already logged in elsewhere, you must wait
ResultSuspended Result = C.k_EResultSuspended // Long running operation (content download) suspended/paused
ResultCancelled Result = C.k_EResultCancelled // Operation canceled (typically by user: content download)
ResultDataCorruption Result = C.k_EResultDataCorruption // Operation canceled because data is ill formed or unrecoverable
ResultDiskFull Result = C.k_EResultDiskFull // Operation canceled - not enough disk space.
ResultRemoteCallFailed Result = C.k_EResultRemoteCallFailed // an remote call or IPC call failed
ResultPasswordUnset Result = C.k_EResultPasswordUnset // Password could not be verified as it's unset server side
ResultExternalAccountUnlinked Result = C.k_EResultExternalAccountUnlinked // External account (PSN, Facebook...) is not linked to a Steam account
ResultPSNTicketInvalid Result = C.k_EResultPSNTicketInvalid // PSN ticket was invalid
ResultExternalAccountAlreadyLinked Result = C.k_EResultExternalAccountAlreadyLinked // External account (PSN, Facebook...) is already linked to some other account, must explicitly request to replace/delete the link first
ResultRemoteFileConflict Result = C.k_EResultRemoteFileConflict // The sync cannot resume due to a conflict between the local and remote files
ResultIllegalPassword Result = C.k_EResultIllegalPassword // The requested new password is not legal
ResultSameAsPreviousValue Result = C.k_EResultSameAsPreviousValue // new value is the same as the old one ( secret question and answer )
ResultAccountLogonDenied Result = C.k_EResultAccountLogonDenied // account login denied due to 2nd factor authentication failure
ResultCannotUseOldPassword Result = C.k_EResultCannotUseOldPassword // The requested new password is not legal
ResultInvalidLoginAuthCode Result = C.k_EResultInvalidLoginAuthCode // account login denied due to auth code invalid
ResultAccountLogonDeniedNoMail Result = C.k_EResultAccountLogonDeniedNoMail // account login denied due to 2nd factor auth failure - and no mail has been sent
ResultHardwareNotCapableOfIPT Result = C.k_EResultHardwareNotCapableOfIPT //
ResultIPTInitError Result = C.k_EResultIPTInitError //
ResultParentalControlRestricted Result = C.k_EResultParentalControlRestricted // operation failed due to parental control restrictions for current user
ResultFacebookQueryError Result = C.k_EResultFacebookQueryError // Facebook query returned an error
ResultExpiredLoginAuthCode Result = C.k_EResultExpiredLoginAuthCode // account login denied due to auth code expired
ResultIPLoginRestrictionFailed Result = C.k_EResultIPLoginRestrictionFailed
ResultAccountLockedDown Result = C.k_EResultAccountLockedDown
ResultAccountLogonDeniedVerifiedEmailRequired Result = C.k_EResultAccountLogonDeniedVerifiedEmailRequired
ResultNoMatchingURL Result = C.k_EResultNoMatchingURL
ResultBadResponse Result = C.k_EResultBadResponse // parse failure, missing field, etc.
ResultRequirePasswordReEntry Result = C.k_EResultRequirePasswordReEntry // The user cannot complete the action until they re-enter their password
ResultValueOutOfRange Result = C.k_EResultValueOutOfRange // the value entered is outside the acceptable range
ResultUnexpectedError Result = C.k_EResultUnexpectedError // something happened that we didn't expect to ever happen
ResultDisabled Result = C.k_EResultDisabled // The requested service has been configured to be unavailable
ResultInvalidCEGSubmission Result = C.k_EResultInvalidCEGSubmission // The set of files submitted to the CEG server are not valid !
ResultRestrictedDevice Result = C.k_EResultRestrictedDevice // The device being used is not allowed to perform this action
ResultRegionLocked Result = C.k_EResultRegionLocked // The action could not be complete because it is region restricted
ResultRateLimitExceeded Result = C.k_EResultRateLimitExceeded // Temporary rate limit exceeded, try again later, different from k_EResultLimitExceeded which may be permanent
ResultAccountLoginDeniedNeedTwoFactor Result = C.k_EResultAccountLoginDeniedNeedTwoFactor // Need two-factor code to login
ResultItemDeleted Result = C.k_EResultItemDeleted // The thing we're trying to access has been deleted
ResultAccountLoginDeniedThrottle Result = C.k_EResultAccountLoginDeniedThrottle // login attempt failed, try to throttle response to possible attacker
ResultTwoFactorCodeMismatch Result = C.k_EResultTwoFactorCodeMismatch // two factor code mismatch
ResultTwoFactorActivationCodeMismatch Result = C.k_EResultTwoFactorActivationCodeMismatch // activation code for two-factor didn't match
ResultAccountAssociatedToMultiplePartners Result = C.k_EResultAccountAssociatedToMultiplePartners // account has been associated with multiple partners
ResultNotModified Result = C.k_EResultNotModified // data not modified
ResultNoMobileDevice Result = C.k_EResultNoMobileDevice // the account does not have a mobile device associated with it
ResultTimeNotSynced Result = C.k_EResultTimeNotSynced // the time presented is out of range or tolerance
ResultSmsCodeFailed Result = C.k_EResultSmsCodeFailed // SMS code failure (no match, none pending, etc.)
ResultAccountLimitExceeded Result = C.k_EResultAccountLimitExceeded // Too many accounts access this resource
ResultAccountActivityLimitExceeded Result = C.k_EResultAccountActivityLimitExceeded // Too many changes to this account
ResultPhoneActivityLimitExceeded Result = C.k_EResultPhoneActivityLimitExceeded // Too many changes to this phone
ResultRefundToWallet Result = C.k_EResultRefundToWallet // Cannot refund to payment method, must use wallet
ResultEmailSendFailure Result = C.k_EResultEmailSendFailure // Cannot send an email
ResultNotSettled Result = C.k_EResultNotSettled // Can't perform operation till payment has settled
ResultNeedCaptcha Result = C.k_EResultNeedCaptcha // Needs to provide a valid captcha
ResultGSLTDenied Result = C.k_EResultGSLTDenied // a game server login token owned by this token's owner has been banned
ResultGSOwnerDenied Result = C.k_EResultGSOwnerDenied // game server owner is denied for other reason (account lock, community ban, vac ban, missing phone)
ResultInvalidItemType Result = C.k_EResultInvalidItemType // the type of thing we were requested to act on is invalid
ResultIPBanned Result = C.k_EResultIPBanned // the ip address has been banned from taking this action
ResultGSLTExpired Result = C.k_EResultGSLTExpired // this token has expired from disuse; can be reset for use
ResultInsufficientFunds Result = C.k_EResultInsufficientFunds // user doesn't have enough wallet funds to complete the action
ResultTooManyPending Result = C.k_EResultTooManyPending // There are too many of this thing pending already
ResultNoSiteLicensesFound Result = C.k_EResultNoSiteLicensesFound // No site licenses found
ResultWGNetworkSendExceeded Result = C.k_EResultWGNetworkSendExceeded // the WG couldn't send a response because we exceeded max network send size
)
// IdentityType is the interface to ESteamNetworkingIdentityType
type IdentityType C.ESteamNetworkingIdentityType
// IdentityType constants
const (
// Dummy/empty/invalid.
// Plese note that if we parse a string that we don't recognize
// but that appears reasonable, we will NOT use this type. Instead
// we'll use k_ESteamNetworkingIdentityType_UnknownType.
IdentityTypeInvalid IdentityType = C.k_ESteamNetworkingIdentityType_Invalid
//
// Basic platform-specific identifiers.
//
IdentityTypeSteamID IdentityType = C.k_ESteamNetworkingIdentityType_SteamID // 64-bit CSteamID
//
// Special identifiers.
//
// Use their IP address (and port) as their "identity".
// These types of identities are always unauthenticated.
// They are useful for porting plain sockets code, and other
// situations where you don't care about authentication. In this
// case, the local identity will be "localhost",
// and the remote address will be their network address.
//
// We use the same type for either IPv4 or IPv6, and
// the address is always store as IPv6. We use IPv4
// mapped addresses to handle IPv4.
IdentityTypeIPAddress IdentityType = C.k_ESteamNetworkingIdentityType_IPAddress
// Generic string/binary blobs. It's up to your app to interpret this.
// This library can tell you if the remote host presented a certificate
// signed by somebody you have chosen to trust, with this identity on it.
// It's up to you to ultimately decide what this identity means.
IdentityTypeGenericString IdentityType = C.k_ESteamNetworkingIdentityType_GenericString
IdentityTypeGenericBytes IdentityType = C.k_ESteamNetworkingIdentityType_GenericBytes
// This identity type is used when we parse a string that looks like is a
// valid identity, just of a kind that we don't recognize. In this case, we
// can often still communicate with the peer! Allowing such identities
// for types we do not recognize useful is very useful for forward
// compatibility.
IdentityTypeUnknownType IdentityType = C.k_ESteamNetworkingIdentityType_UnknownType
)
// Identity is the interface to SteamNetworkingIdentity
//
// An abstract way to represent the identity of a network host. All identities can
// be represented as simple string. Furthermore, this string representation is actually
// used on the wire in several places, even though it is less efficient, in order to
// facilitate forward compatibility. (Old client code can handle an identity type that
// it doesn't understand.)
type Identity = C.SteamNetworkingIdentity
// ParseIdentity is the interface to SteamNetworkingIdentity::ParseString
//
// Parse back a string that was generated using ToString. If we don't understand the
// string, but it looks "reasonable" (it matches the pattern type:<type-data> and doesn't
// have any funky characters, etc), then we will return true, and the type is set to
// k_ESteamNetworkingIdentityType_UnknownType. false will only be returned if the string
// looks invalid.
func ParseIdentity(id string) *Identity {
str := C.CString(id)
defer C.free(unsafe.Pointer(str))
var res Identity
if C.SteamAPI_SteamNetworkingIdentity_ParseString(&res, (C.size_t)(unsafe.Sizeof(res)), str) {
return &res
}
return nil
}
// Valid is the interface to SteamNetworkingIdentity::IsInvalid
//
// Return false if we are the invalid type. Does not make any other validity checks (e.g. is SteamID actually valid)
func (id *Identity) Valid() bool {
return id != nil && !(bool)(C.SteamAPI_SteamNetworkingIdentity_IsInvalid(id))
}
// Equals is the interface to SteamNetworkingIdentity::IsEqualTo
//
// See if two identities are identical.
func (id *Identity) Equals(other *Identity) bool {
return (bool)(C.SteamAPI_SteamNetworkingIdentity_IsEqualTo(id, other))
}
// Valid is the interface to SteamNetworkingIdentity::ToString
//
// Print to a human-readable string. This is suitable for debug messages
// or any other time you need to encode the identity as a string. It has a
// URL-like format (type:<type-data>). Your buffer should be at least
// k_cchMaxString bytes big to avoid truncation.
func (id *Identity) String() string {
var buf [C.k_cchSteamNetworkingIdentityMaxString]C.char
C.SteamAPI_SteamNetworkingIdentity_ToString(id, &buf[0], (C.size_t)(len(buf)))
return C.GoString(&buf[0])
}
// Type returns m_eDataType
func (id *Identity) Type() IdentityType { return (IdentityType)(id.m_eType) }
// IPAddr is the interface to SteamNetworkingIPAddr
//
// Store an IP and port. IPv6 is always used; IPv4 is represented using
// "IPv4-mapped" addresses: IPv4 aa.bb.cc.dd => IPv6 ::ffff:aabb:ccdd
// (RFC 4291 section 2.5.5.2.)
type IPAddr = C.SteamNetworkingIPAddr
// NewIPAddr maps net.UDPAddr to IPAddr
func NewIPAddr(addr *net.UDPAddr) *IPAddr {
port := (C.uint16_t)(addr.Port)
var res IPAddr
C.SteamAPI_SteamNetworkingIPAddr_Clear(&res)
if ip4 := addr.IP.To4(); ip4 != nil {
C.SteamAPI_SteamNetworkingIPAddr_SetIPv4(&res, (C.uint32_t)(binary.BigEndian.Uint32(ip4)), port)
} else if ip16 := addr.IP.To16(); ip16 != nil {
C.SteamAPI_SteamNetworkingIPAddr_SetIPv6(&res, (*C.uint8_t)(&ip16[0]), port)
} else {
C.SteamAPI_SteamNetworkingIPAddr_Clear(&res)
}
return &res
}
// UDPAddr returns the corresponding net.UDPAddr
func (addr *IPAddr) UDPAddr() *net.UDPAddr {
ip := make(net.IP, net.IPv6len)
copy(ip, addr.m_ip[:])
return &net.UDPAddr{
IP: ip,
Port: int(addr.m_port),
}
}
// SendFlags used to set options for message sending
type SendFlags int
// SendFlags constants
const (
// Send the message unreliably. Can be lost. Messages *can* be larger than a
// single MTU (UDP packet), but there is no retransmission, so if any piece
// of the message is lost, the entire message will be dropped.
//
// The sending API does have some knowledge of the underlying connection, so
// if there is no NAT-traversal accomplished or there is a recognized adjustment
// happening on the connection, the packet will be batched until the connection
// is open again.
//
// Migration note: This is not exactly the same as k_EP2PSendUnreliable! You
// probably want k_ESteamNetworkingSendType_UnreliableNoNagle
SendUnreliable SendFlags = C.k_nSteamNetworkingSend_Unreliable
// Disable Nagle's algorithm.
// By default, Nagle's algorithm is applied to all outbound messages. This means
// that the message will NOT be sent immediately, in case further messages are
// sent soon after you send this, which can be grouped together. Any time there
// is enough buffered data to fill a packet, the packets will be pushed out immediately,
// but partially-full packets not be sent until the Nagle timer expires. See
// ISteamNetworkingSockets::FlushMessagesOnConnection, ISteamNetworkingMessages::FlushMessagesToUser
//
// NOTE: Don't just send every message without Nagle because you want packets to get there
// quicker. Make sure you understand the problem that Nagle is solving before disabling it.
// If you are sending small messages, often many at the same time, then it is very likely that
// it will be more efficient to leave Nagle enabled. A typical proper use of this flag is
// when you are sending what you know will be the last message sent for a while (e.g. the last
// in the server simulation tick to a particular client), and you use this flag to flush all
// messages.
SendNoNagle SendFlags = C.k_nSteamNetworkingSend_NoNagle
// Send a message unreliably, bypassing Nagle's algorithm for this message and any messages
// currently pending on the Nagle timer. This is equivalent to using k_ESteamNetworkingSend_Unreliable
// and then immediately flushing the messages using ISteamNetworkingSockets::FlushMessagesOnConnection
// or ISteamNetworkingMessages::FlushMessagesToUser. (But using this flag is more efficient since you
// only make one API call.)
SendUnreliableNoNagle SendFlags = C.k_nSteamNetworkingSend_UnreliableNoNagle
// If the message cannot be sent very soon (because the connection is still doing some initial
// handshaking, route negotiations, etc), then just drop it. This is only applicable for unreliable
// messages. Using this flag on reliable messages is invalid.
SendNoDelay SendFlags = C.k_nSteamNetworkingSend_NoDelay
// Send an unreliable message, but if it cannot be sent relatively quickly, just drop it instead of queuing it.
// This is useful for messages that are not useful if they are excessively delayed, such as voice data.
// NOTE: The Nagle algorithm is not used, and if the message is not dropped, any messages waiting on the
// Nagle timer are immediately flushed.
//
// A message will be dropped under the following circumstances:
// - the connection is not fully connected. (E.g. the "Connecting" or "FindingRoute" states)
// - there is a sufficiently large number of messages queued up already such that the current message
// will not be placed on the wire in the next ~200ms or so.
//
// If a message is dropped for these reasons, k_EResultIgnored will be returned.
SendUnreliableNoDelay SendFlags = C.k_nSteamNetworkingSend_UnreliableNoDelay
// Reliable message send. Can send up to k_cbMaxSteamNetworkingSocketsMessageSizeSend bytes in a single message.
// Does fragmentation/re-assembly of messages under the hood, as well as a sliding window for
// efficient sends of large chunks of data.
//
// The Nagle algorithm is used. See notes on k_ESteamNetworkingSendType_Unreliable for more details.
// See k_ESteamNetworkingSendType_ReliableNoNagle, ISteamNetworkingSockets::FlushMessagesOnConnection,
// ISteamNetworkingMessages::FlushMessagesToUser
//
// Migration note: This is NOT the same as k_EP2PSendReliable, it's more like k_EP2PSendReliableWithBuffering
SendReliable SendFlags = C.k_nSteamNetworkingSend_Reliable
// Send a message reliably, but bypass Nagle's algorithm.
//
// Migration note: This is equivalent to k_EP2PSendReliable
SendReliableNoNagle SendFlags = C.k_nSteamNetworkingSend_ReliableNoNagle
// By default, message sending is queued, and the work of encryption and talking to
// the operating system sockets, etc is done on a service thread. This is usually a
// a performance win when messages are sent from the "main thread". However, if this
// flag is set, and data is ready to be sent immediately (either from this message
// or earlier queued data), then that work will be done in the current thread, before
// the current call returns. If data is not ready to be sent (due to rate limiting
// or Nagle), then this flag has no effect.
//
// This is an advanced flag used to control performance at a very low level. For
// most applications running on modern hardware with more than one CPU core, doing
// the work of sending on a service thread will yield the best performance. Only
// use this flag if you have a really good reason and understand what you are doing.
// Otherwise you will probably just make performance worse.
SendUseCurrentThread SendFlags = C.k_nSteamNetworkingSend_UseCurrentThread
)
// Message constants
const (
// Max size of a single message that we can SEND.
MaxMessageSizeSend = C.k_cbMaxSteamNetworkingSocketsMessageSizeSend
// Max size of a message that we are wiling to *receive*.
MaxMessageSizeRecv = C.k_cbMaxMessageSizeRecv
)
// Message is the interface to SteamNetworkingMessage_t
//
// A message that has been received.
type Message = C.SteamNetworkingMessage_t
// Release is the interface to SteamNetworkingMessage_t::Release
//
// You MUST call this when you're done with the object,
// to free up memory, etc.
func (msg *Message) Release() {
C.SteamAPI_SteamNetworkingMessage_t_Release(msg)
}
// Payload returns m_pData
func (msg *Message) Payload() []byte {
return (*[1 << 31]byte)(msg.m_pData)[:msg.m_cbSize:msg.m_cbSize]
}
// Size returns m_cbSize
//
// Size of the payload.
func (msg *Message) Size() int { return (int)(msg.m_cbSize) }
// Conn returns m_conn
//
// For messages received on connections: what connection did this come from?
// For outgoing messages: what connection to send it to?
// Not used when using the ISteamNetworkingMessages interface
func (msg *Message) Conn() Connection { return (Connection)(msg.m_conn) }
// PeerIdentity returns m_identityPeer
//
// For messages received on connections: what connection did this come from?
// For outgoing messages: what connection to send it to?
// Not used when using the ISteamNetworkingMessages interface
func (msg *Message) PeerIdentity() *Identity { return &msg.m_identityPeer }
// UserData returns m_m_nConnUserDataconn
//
// For messages received on connections, this is the user data
// associated with the connection.
//
// This is *usually* the same as calling GetConnection() and then
// fetching the user data associated with that connection, but for
// the following subtle differences:
//
// - This user data will match the connection's user data at the time
// is captured at the time the message is returned by the API.
// If you subsequently change the userdata on the connection,
// this won't be updated.
// - This is an inline call, so it's *much* faster.
// - You might have closed the connection, so fetching the user data
// would not be possible.
//
// Not used when sending messages,
func (msg *Message) UserData() int64 { return (int64)(msg.m_nConnUserData) }
// Timestamp returns m_usecTimeReceived
//
// Local timestamp when the message was received
// Not used for outbound messages.
func (msg *Message) Timestamp() Timestamp { return (Timestamp)(msg.m_usecTimeReceived) }
// MessageNumber returns m_nMessageNumber
//
// Message number assigned by the sender.
// This is not used for outbound messages
func (msg *Message) MessageNumber() int64 { return (int64)(msg.m_nMessageNumber) }
// Flags returns m_nFlags
//
// Bitmask of k_nSteamNetworkingSend_xxx flags.
// For received messages, only the k_nSteamNetworkingSend_Reliable bit is valid.
// For outbound messages, all bits are relevant
func (msg *Message) Flags() SendFlags { return (SendFlags)(msg.m_nFlags) }
// ConnectionState is the interface to ESteamNetworkingConnectionState
//
// High level connection status
type ConnectionState C.ESteamNetworkingConnectionState
// ConnectionState constants
const (
// Dummy value used to indicate an error condition in the API.
// Specified connection doesn't exist or has already been closed.
ConnectionStateNone ConnectionState = C.k_ESteamNetworkingConnectionState_None
// We are trying to establish whether peers can talk to each other,
// whether they WANT to talk to each other, perform basic auth,
// and exchange crypt keys.
//
// - For connections on the "client" side (initiated locally):
// We're in the process of trying to establish a connection.
// Depending on the connection type, we might not know who they are.
// Note that it is not possible to tell if we are waiting on the
// network to complete handshake packets, or for the application layer
// to accept the connection.
//
// - For connections on the "server" side (accepted through listen socket):
// We have completed some basic handshake and the client has presented
// some proof of identity. The connection is ready to be accepted
// using AcceptConnection().
//
// In either case, any unreliable packets sent now are almost certain
// to be dropped. Attempts to receive packets are guaranteed to fail.
// You may send messages if the send mode allows for them to be queued.
// but if you close the connection before the connection is actually
// established, any queued messages will be discarded immediately.
// (We will not attempt to flush the queue and confirm delivery to the
// remote host, which ordinarily happens when a connection is closed.)
ConnectionStateConnecting ConnectionState = C.k_ESteamNetworkingConnectionState_Connecting
// Some connection types use a back channel or trusted 3rd party
// for earliest communication. If the server accepts the connection,
// then these connections switch into the rendezvous state. During this
// state, we still have not yet established an end-to-end route (through
// the relay network), and so if you send any messages unreliable, they
// are going to be discarded.
ConnectionStateFindingRoute ConnectionState = C.k_ESteamNetworkingConnectionState_FindingRoute
// We've received communications from our peer (and we know
// who they are) and are all good. If you close the connection now,
// we will make our best effort to flush out any reliable sent data that
// has not been acknowledged by the peer. (But note that this happens
// from within the application process, so unlike a TCP connection, you are
// not totally handing it off to the operating system to deal with it.)
ConnectionStateConnected ConnectionState = C.k_ESteamNetworkingConnectionState_Connected
// Connection has been closed by our peer, but not closed locally.
// The connection still exists from an API perspective. You must close the
// handle to free up resources. If there are any messages in the inbound queue,
// you may retrieve them. Otherwise, nothing may be done with the connection
// except to close it.
//
// This stats is similar to CLOSE_WAIT in the TCP state machine.
ConnectionStateClosedByPeer ConnectionState = C.k_ESteamNetworkingConnectionState_ClosedByPeer
// A disruption in the connection has been detected locally. (E.g. timeout,
// local internet connection disrupted, etc.)
//
// The connection still exists from an API perspective. You must close the
// handle to free up resources.
//
// Attempts to send further messages will fail. Any remaining received messages
// in the queue are available.
ConnectionStateProblemDetectedLocally ConnectionState = C.k_ESteamNetworkingConnectionState_ProblemDetectedLocally
)
// ConnectionEndReason is the interface to ESteamNetConnectionEnd
//
// Enumerate various causes of connection termination. These are designed to work similar
// to HTTP error codes: the numeric range gives you a rough classification as to the source
// of the problem.
type ConnectionEndReason C.ESteamNetConnectionEnd
// ConnectionEndReason constants
const (
// Invalid/sentinel value
ConnectionEndInvalid ConnectionEndReason = C.k_ESteamNetConnectionEnd_Invalid
//
// Application codes. These are the values you will pass to
// ISteamNetworkingSockets::CloseConnection. You can use these codes if
// you want to plumb through application-specific reason codes. If you don't
// need this facility, feel free to always pass
// k_ESteamNetConnectionEnd_App_Generic.
//
// The distinction between "normal" and "exceptional" termination is
// one you may use if you find useful, but it's not necessary for you
// to do so. The only place where we distinguish between normal and
// exceptional is in connection analytics. If a significant
// proportion of connections terminates in an exceptional manner,
// this can trigger an alert.
//
// 1xxx: Application ended the connection in a "usual" manner.
// E.g.: user intentionally disconnected from the server,
// gameplay ended normally, etc
ConnectionEndAppMin ConnectionEndReason = C.k_ESteamNetConnectionEnd_App_Min
ConnectionEndAppGeneric ConnectionEndReason = C.k_ESteamNetConnectionEnd_App_Generic
// Use codes in this range for "normal" disconnection
ConnectionEndAppMax ConnectionEndReason = C.k_ESteamNetConnectionEnd_App_Max
// 2xxx: Application ended the connection in some sort of exceptional
// or unusual manner that might indicate a bug or configuration
// issue.
//
ConnectionEndAppExceptionMin ConnectionEndReason = C.k_ESteamNetConnectionEnd_AppException_Min
ConnectionEndAppExceptionGeneric ConnectionEndReason = C.k_ESteamNetConnectionEnd_AppException_Generic
// Use codes in this range for "unusual" disconnection
ConnectionEndAppExceptionMax ConnectionEndReason = C.k_ESteamNetConnectionEnd_AppException_Max
//
// System codes. These will be returned by the system when
// the connection state is k_ESteamNetworkingConnectionState_ClosedByPeer
// or k_ESteamNetworkingConnectionState_ProblemDetectedLocally. It is
// illegal to pass a code in this range to ISteamNetworkingSockets::CloseConnection
//
// 3xxx: Connection failed or ended because of problem with the
// local host or their connection to the Internet.
ConnectionEndLocalMin ConnectionEndReason = C.k_ESteamNetConnectionEnd_Local_Min
// You cannot do what you want to do because you're running in offline mode.
ConnectionEndLocalOfflineMode ConnectionEndReason = C.k_ESteamNetConnectionEnd_Local_OfflineMode
// We're having trouble contacting many (perhaps all) relays.
// Since it's unlikely that they all went offline at once, the best
// explanation is that we have a problem on our end. Note that we don't
// bother distinguishing between "many" and "all", because in practice,
// it takes time to detect a connection problem, and by the time
// the connection has timed out, we might not have been able to
// actively probe all of the relay clusters, even if we were able to
// contact them at one time. So this code just means that:
//
// * We don't have any recent successful communication with any relay.
// * We have evidence of recent failures to communicate with multiple relays.
ConnectionEndLocalManyRelayConnectivity ConnectionEndReason = C.k_ESteamNetConnectionEnd_Local_ManyRelayConnectivity
// A hosted server is having trouble talking to the relay
// that the client was using, so the problem is most likely
// on our end
ConnectionEndLocalHostedServerPrimaryRelay ConnectionEndReason = C.k_ESteamNetConnectionEnd_Local_HostedServerPrimaryRelay
// We're not able to get the network config. This is
// *almost* always a local issue, since the network config
// comes from the CDN, which is pretty darn reliable.
ConnectionEndLocalNetworkConfig ConnectionEndReason = C.k_ESteamNetConnectionEnd_Local_NetworkConfig
// Steam rejected our request because we don't have rights
// to do this.
ConnectionEndLocalRights ConnectionEndReason = C.k_ESteamNetConnectionEnd_Local_Rights
ConnectionEndLocalMax ConnectionEndReason = C.k_ESteamNetConnectionEnd_Local_Max
// 4xxx: Connection failed or ended, and it appears that the
// cause does NOT have to do with the local host or their
// connection to the Internet. It could be caused by the
// remote host, or it could be somewhere in between.
ConnectionEndRemoteMin ConnectionEndReason = C.k_ESteamNetConnectionEnd_Remote_Min
// The connection was lost, and as far as we can tell our connection
// to relevant services (relays) has not been disrupted. This doesn't
// mean that the problem is "their fault", it just means that it doesn't
// appear that we are having network issues on our end.
ConnectionEndRemoteTimeout ConnectionEndReason = C.k_ESteamNetConnectionEnd_Remote_Timeout
// Something was invalid with the cert or crypt handshake
// info you gave me, I don't understand or like your key types,
// etc.
ConnectionEndRemoteBadCrypt ConnectionEndReason = C.k_ESteamNetConnectionEnd_Remote_BadCrypt
// You presented me with a cert that was I was able to parse
// and *technically* we could use encrypted communication.
// But there was a problem that prevents me from checking your identity
// or ensuring that somebody int he middle can't observe our communication.
// E.g.: - the CA key was missing (and I don't accept unsigned certs)
// - The CA key isn't one that I trust,
// - The cert doesn't was appropriately restricted by app, user, time, data center, etc.
// - The cert wasn't issued to you.
// - etc
ConnectionEndRemoteBadCert ConnectionEndReason = C.k_ESteamNetConnectionEnd_Remote_BadCert
// We couldn't rendezvous with the remote host because
// they aren't logged into Steam
ConnectionEndRemoteNotLoggedIn ConnectionEndReason = C.k_ESteamNetConnectionEnd_Remote_NotLoggedIn
// We couldn't rendezvous with the remote host because
// they aren't running the right application.
ConnectionEndRemoteNotRunningApp ConnectionEndReason = C.k_ESteamNetConnectionEnd_Remote_NotRunningApp
// Something wrong with the protocol version you are using.
// (Probably the code you are running is too old.)
ConnectionEndRemoteBadProtocolVersion ConnectionEndReason = C.k_ESteamNetConnectionEnd_Remote_BadProtocolVersion
ConnectionEndRemoteMax ConnectionEndReason = C.k_ESteamNetConnectionEnd_Remote_Max
// 5xxx: Connection failed for some other reason.
ConnectionEndMiscMin ConnectionEndReason = C.k_ESteamNetConnectionEnd_Misc_Min
// A failure that isn't necessarily the result of a software bug,
// but that should happen rarely enough that it isn't worth specifically
// writing UI or making a localized message for.
// The debug string should contain further details.
ConnectionEndMiscGeneric ConnectionEndReason = C.k_ESteamNetConnectionEnd_Misc_Generic
// Generic failure that is most likely a software bug.
ConnectionEndMiscInternalError ConnectionEndReason = C.k_ESteamNetConnectionEnd_Misc_InternalError