@quenty/timesyncservice 13.18.2 → 13.18.3-canary.550.afa1b3b.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [13.18.3-canary.550.afa1b3b.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/timesyncservice@13.18.2...@quenty/timesyncservice@13.18.3-canary.550.afa1b3b.0) (2025-04-10)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @quenty/timesyncservice
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
6
14
|
## [13.18.2](https://github.com/Quenty/NevermoreEngine/compare/@quenty/timesyncservice@13.18.0...@quenty/timesyncservice@13.18.2) (2025-04-07)
|
|
7
15
|
|
|
8
16
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/timesyncservice",
|
|
3
|
-
"version": "13.18.
|
|
3
|
+
"version": "13.18.3-canary.550.afa1b3b.0",
|
|
4
4
|
"description": "Quenty's TimeSyncService keeps time synchronized between all clients and the server",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -26,18 +26,18 @@
|
|
|
26
26
|
"Quenty"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@quenty/baseobject": "
|
|
30
|
-
"@quenty/loader": "
|
|
31
|
-
"@quenty/maid": "
|
|
32
|
-
"@quenty/promise": "
|
|
33
|
-
"@quenty/remoting": "
|
|
34
|
-
"@quenty/rx": "
|
|
35
|
-
"@quenty/signal": "
|
|
36
|
-
"@quenty/table": "
|
|
37
|
-
"@quenty/valueobject": "
|
|
29
|
+
"@quenty/baseobject": "10.8.3-canary.550.afa1b3b.0",
|
|
30
|
+
"@quenty/loader": "10.8.3-canary.550.afa1b3b.0",
|
|
31
|
+
"@quenty/maid": "3.4.3-canary.550.afa1b3b.0",
|
|
32
|
+
"@quenty/promise": "10.10.4-canary.550.afa1b3b.0",
|
|
33
|
+
"@quenty/remoting": "12.18.3-canary.550.afa1b3b.0",
|
|
34
|
+
"@quenty/rx": "13.17.3-canary.550.afa1b3b.0",
|
|
35
|
+
"@quenty/signal": "7.10.3-canary.550.afa1b3b.0",
|
|
36
|
+
"@quenty/table": "3.7.4-canary.550.afa1b3b.0",
|
|
37
|
+
"@quenty/valueobject": "13.17.3-canary.550.afa1b3b.0"
|
|
38
38
|
},
|
|
39
39
|
"publishConfig": {
|
|
40
40
|
"access": "public"
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "afa1b3b99b862698c3ab46009497bd507150867c"
|
|
43
43
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
Master clock on the server
|
|
3
4
|
@class MasterClock
|
|
@@ -7,11 +8,23 @@ local require = require(script.Parent.loader).load(script)
|
|
|
7
8
|
|
|
8
9
|
local BaseObject = require("BaseObject")
|
|
9
10
|
local Rx = require("Rx")
|
|
11
|
+
local _Observable = require("Observable")
|
|
10
12
|
|
|
11
13
|
local MasterClock = setmetatable({}, BaseObject)
|
|
12
14
|
MasterClock.__index = MasterClock
|
|
13
15
|
MasterClock.ClassName = "MasterClock"
|
|
14
16
|
|
|
17
|
+
export type ClockFunction = () -> number
|
|
18
|
+
|
|
19
|
+
export type MasterClock = typeof(setmetatable(
|
|
20
|
+
{} :: {
|
|
21
|
+
_remoteEvent: RemoteEvent,
|
|
22
|
+
_remoteFunction: RemoteFunction,
|
|
23
|
+
_clockFunction: ClockFunction,
|
|
24
|
+
},
|
|
25
|
+
{} :: typeof({ __index = MasterClock })
|
|
26
|
+
)) & BaseObject.BaseObject
|
|
27
|
+
|
|
15
28
|
--[=[
|
|
16
29
|
Constructs a new MasterClock
|
|
17
30
|
|
|
@@ -19,8 +32,8 @@ MasterClock.ClassName = "MasterClock"
|
|
|
19
32
|
@param remoteFunction RemoteFunction
|
|
20
33
|
@return MasterClock
|
|
21
34
|
]=]
|
|
22
|
-
function MasterClock.new(remoteEvent: RemoteEvent, remoteFunction: RemoteFunction)
|
|
23
|
-
local self = setmetatable(BaseObject.new(), MasterClock)
|
|
35
|
+
function MasterClock.new(remoteEvent: RemoteEvent, remoteFunction: RemoteFunction): MasterClock
|
|
36
|
+
local self: MasterClock = setmetatable(BaseObject.new() :: any, MasterClock)
|
|
24
37
|
|
|
25
38
|
self._remoteEvent = remoteEvent or error("No remoteEvent")
|
|
26
39
|
self._remoteFunction = remoteFunction or error("No remoteFunction")
|
|
@@ -56,7 +69,7 @@ end
|
|
|
56
69
|
|
|
57
70
|
@return function
|
|
58
71
|
]=]
|
|
59
|
-
function MasterClock
|
|
72
|
+
function MasterClock.GetClockFunction(self: MasterClock): ClockFunction
|
|
60
73
|
return self._clockFunction
|
|
61
74
|
end
|
|
62
75
|
|
|
@@ -65,15 +78,15 @@ end
|
|
|
65
78
|
|
|
66
79
|
@return Observable<number>
|
|
67
80
|
]=]
|
|
68
|
-
function MasterClock
|
|
69
|
-
return Rx.of(0)
|
|
81
|
+
function MasterClock.ObservePing(_self: MasterClock): _Observable.Observable<number>
|
|
82
|
+
return Rx.of(0) :: any
|
|
70
83
|
end
|
|
71
84
|
|
|
72
85
|
--[=[
|
|
73
86
|
Returns true if the manager has synced with the server
|
|
74
87
|
@return boolean
|
|
75
88
|
]=]
|
|
76
|
-
function MasterClock
|
|
89
|
+
function MasterClock.IsSynced(_self: MasterClock): boolean
|
|
77
90
|
return true
|
|
78
91
|
end
|
|
79
92
|
|
|
@@ -81,25 +94,25 @@ end
|
|
|
81
94
|
Returns estimated ping in seconds
|
|
82
95
|
@return number
|
|
83
96
|
]=]
|
|
84
|
-
function MasterClock
|
|
85
|
-
return
|
|
97
|
+
function MasterClock.GetPing(_self: MasterClock): number
|
|
98
|
+
return 0
|
|
86
99
|
end
|
|
87
100
|
|
|
88
101
|
--[=[
|
|
89
102
|
Returns the sycncronized time
|
|
90
103
|
@return number
|
|
91
104
|
]=]
|
|
92
|
-
function MasterClock
|
|
105
|
+
function MasterClock.GetTime(_self: MasterClock): number
|
|
93
106
|
return tick()
|
|
94
107
|
end
|
|
95
108
|
|
|
96
|
-
function MasterClock
|
|
109
|
+
function MasterClock._forceSync(self: MasterClock): ()
|
|
97
110
|
-- start the sync process with all slave clocks.
|
|
98
111
|
local timeOne = self:GetTime()
|
|
99
112
|
self._remoteEvent:FireAllClients(timeOne)
|
|
100
113
|
end
|
|
101
114
|
|
|
102
|
-
function MasterClock
|
|
115
|
+
function MasterClock._handleDelayRequest(self: MasterClock, timeThree: number): number
|
|
103
116
|
-- Client sends back message to get the SM_Difference.
|
|
104
117
|
-- returns slaveMasterDifference
|
|
105
118
|
local timeFour = self:GetTime()
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
Slave clock on the client
|
|
3
4
|
@class SlaveClock
|
|
@@ -7,12 +8,30 @@ local require = require(script.Parent.loader).load(script)
|
|
|
7
8
|
|
|
8
9
|
local BaseObject = require("BaseObject")
|
|
9
10
|
local ValueObject = require("ValueObject")
|
|
11
|
+
local _Observable = require("Observable")
|
|
10
12
|
|
|
11
13
|
local SlaveClock = setmetatable({}, BaseObject)
|
|
12
14
|
SlaveClock.__index = SlaveClock
|
|
13
15
|
SlaveClock.ClassName = "SlaveClock"
|
|
14
16
|
SlaveClock._offset = -1 -- Set uncalculated values to -1
|
|
15
17
|
|
|
18
|
+
export type ClockFunction = () -> number
|
|
19
|
+
|
|
20
|
+
export type SlaveClock = typeof(setmetatable(
|
|
21
|
+
{} :: {
|
|
22
|
+
_remoteEvent: RemoteEvent,
|
|
23
|
+
_remoteFunction: RemoteFunction,
|
|
24
|
+
_clockFunction: ClockFunction,
|
|
25
|
+
_ping: ValueObject.ValueObject<number>,
|
|
26
|
+
_offset: number,
|
|
27
|
+
_pneWayDelay: number,
|
|
28
|
+
_syncedBindable: BindableEvent,
|
|
29
|
+
|
|
30
|
+
SyncedEvent: RBXScriptSignal,
|
|
31
|
+
},
|
|
32
|
+
{} :: typeof({ __index = SlaveClock })
|
|
33
|
+
)) & BaseObject.BaseObject
|
|
34
|
+
|
|
16
35
|
--[=[
|
|
17
36
|
Constructs a new SlaveClock
|
|
18
37
|
|
|
@@ -20,8 +39,8 @@ SlaveClock._offset = -1 -- Set uncalculated values to -1
|
|
|
20
39
|
@param remoteFunction RemoteFunction
|
|
21
40
|
@return SlaveClock
|
|
22
41
|
]=]
|
|
23
|
-
function SlaveClock.new(remoteEvent: RemoteEvent, remoteFunction: RemoteFunction)
|
|
24
|
-
local self = setmetatable(BaseObject.new(), SlaveClock)
|
|
42
|
+
function SlaveClock.new(remoteEvent: RemoteEvent, remoteFunction: RemoteFunction): SlaveClock
|
|
43
|
+
local self: SlaveClock = setmetatable(BaseObject.new() :: any, SlaveClock)
|
|
25
44
|
|
|
26
45
|
self._remoteEvent = remoteEvent or error("No remoteEvent")
|
|
27
46
|
self._remoteFunction = remoteFunction or error("No remoteFunction")
|
|
@@ -48,11 +67,11 @@ end
|
|
|
48
67
|
|
|
49
68
|
@return function
|
|
50
69
|
]=]
|
|
51
|
-
function SlaveClock
|
|
70
|
+
function SlaveClock.GetClockFunction(self: SlaveClock): ClockFunction
|
|
52
71
|
return self._clockFunction
|
|
53
72
|
end
|
|
54
73
|
|
|
55
|
-
function SlaveClock
|
|
74
|
+
function SlaveClock.ObservePing(self: SlaveClock): _Observable.Observable<number>
|
|
56
75
|
return self._ping:Observe()
|
|
57
76
|
end
|
|
58
77
|
|
|
@@ -61,7 +80,7 @@ end
|
|
|
61
80
|
@param syncedTime number
|
|
62
81
|
@return number
|
|
63
82
|
]=]
|
|
64
|
-
function SlaveClock
|
|
83
|
+
function SlaveClock.TickToSyncedTime(self: SlaveClock, syncedTime: number): number
|
|
65
84
|
return syncedTime - self._offset
|
|
66
85
|
end
|
|
67
86
|
|
|
@@ -69,7 +88,7 @@ end
|
|
|
69
88
|
Returns the sycncronized time
|
|
70
89
|
@return number
|
|
71
90
|
]=]
|
|
72
|
-
function SlaveClock
|
|
91
|
+
function SlaveClock.GetTime(self: SlaveClock): number
|
|
73
92
|
if not self:IsSynced() then
|
|
74
93
|
error("[SlaveClock.GetTime] - Slave clock is not yet synced")
|
|
75
94
|
end
|
|
@@ -81,11 +100,11 @@ end
|
|
|
81
100
|
Returns true if the manager has synced with the server
|
|
82
101
|
@return boolean
|
|
83
102
|
]=]
|
|
84
|
-
function SlaveClock
|
|
103
|
+
function SlaveClock.IsSynced(self: SlaveClock): boolean
|
|
85
104
|
return self._offset ~= -1
|
|
86
105
|
end
|
|
87
106
|
|
|
88
|
-
function SlaveClock
|
|
107
|
+
function SlaveClock._getLocalTime(_self: SlaveClock)
|
|
89
108
|
-- NOTE: Do not change this without changing :TickToSyncedTime
|
|
90
109
|
return tick()
|
|
91
110
|
end
|
|
@@ -94,11 +113,11 @@ end
|
|
|
94
113
|
Returns estimated ping in seconds
|
|
95
114
|
@return number
|
|
96
115
|
]=]
|
|
97
|
-
function SlaveClock
|
|
116
|
+
function SlaveClock.GetPing(self: SlaveClock): number
|
|
98
117
|
return self._ping.Value
|
|
99
118
|
end
|
|
100
119
|
|
|
101
|
-
function SlaveClock
|
|
120
|
+
function SlaveClock._handleSyncEventAsync(self: SlaveClock, timeOne: number)
|
|
102
121
|
local timeTwo = self:_getLocalTime() -- We can't actually get hardware stuff, so we'll send T1 immediately.
|
|
103
122
|
local masterSlaveDifference = timeTwo - timeOne -- We have Offst + MS Delay
|
|
104
123
|
|
|
@@ -126,8 +145,8 @@ function SlaveClock:_handleSyncEventAsync(timeOne)
|
|
|
126
145
|
one_way_delay = (MSDelay + SMDelay) / 2
|
|
127
146
|
]]
|
|
128
147
|
|
|
129
|
-
local offset = (masterSlaveDifference - slaveMasterDifference)/2
|
|
130
|
-
local oneWayDelay = (masterSlaveDifference + slaveMasterDifference)/2
|
|
148
|
+
local offset = (masterSlaveDifference - slaveMasterDifference) / 2
|
|
149
|
+
local oneWayDelay = (masterSlaveDifference + slaveMasterDifference) / 2
|
|
131
150
|
|
|
132
151
|
self._offset = offset -- Estimated difference between server/client
|
|
133
152
|
self._pneWayDelay = oneWayDelay -- Estimated time for network events to send. (MSDelay/SMDelay)
|
|
@@ -136,7 +155,7 @@ function SlaveClock:_handleSyncEventAsync(timeOne)
|
|
|
136
155
|
self._syncedBindable:Fire()
|
|
137
156
|
end
|
|
138
157
|
|
|
139
|
-
function SlaveClock
|
|
158
|
+
function SlaveClock._sendDelayRequestAsync(self: SlaveClock, timeThree)
|
|
140
159
|
return self._remoteFunction:InvokeServer(timeThree)
|
|
141
160
|
end
|
|
142
161
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
@class TimeSyncConstants
|
|
3
4
|
]=]
|
|
@@ -7,6 +8,6 @@ local require = require(script.Parent.loader).load(script)
|
|
|
7
8
|
local Table = require("Table")
|
|
8
9
|
|
|
9
10
|
return Table.readonly({
|
|
10
|
-
REMOTE_EVENT_NAME = "TimeSyncServiceRemoteEvent"
|
|
11
|
-
REMOTE_FUNCTION_NAME = "TimeSyncServiceRemoteFunction"
|
|
12
|
-
})
|
|
11
|
+
REMOTE_EVENT_NAME = "TimeSyncServiceRemoteEvent",
|
|
12
|
+
REMOTE_FUNCTION_NAME = "TimeSyncServiceRemoteFunction",
|
|
13
|
+
})
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
Syncronizes time between the server and client. This creates a shared timestamp that can be used to reasonably time
|
|
3
4
|
events between the server and client.
|
|
@@ -21,18 +22,28 @@ local Rx = require("Rx")
|
|
|
21
22
|
local SlaveClock = require("SlaveClock")
|
|
22
23
|
local TimeSyncConstants = require("TimeSyncConstants")
|
|
23
24
|
local TimeSyncUtils = require("TimeSyncUtils")
|
|
25
|
+
local _Observable = require("Observable")
|
|
24
26
|
|
|
25
27
|
local TimeSyncService = {}
|
|
26
28
|
TimeSyncService.ServiceName = "TimeSyncService"
|
|
27
29
|
|
|
30
|
+
export type SyncedClock = MasterClock.MasterClock | SlaveClock.SlaveClock
|
|
31
|
+
|
|
32
|
+
export type TimeSyncService = typeof(setmetatable(
|
|
33
|
+
{} :: {
|
|
34
|
+
_clockPromise: Promise.Promise<SyncedClock>,
|
|
35
|
+
_maid: Maid.Maid,
|
|
36
|
+
},
|
|
37
|
+
{} :: typeof({ __index = TimeSyncService })
|
|
38
|
+
))
|
|
39
|
+
|
|
28
40
|
--[=[
|
|
29
41
|
Initializes the TimeSyncService
|
|
30
42
|
]=]
|
|
31
|
-
function TimeSyncService
|
|
32
|
-
assert(not self._clockPromise, "TimeSyncService is already initialized!")
|
|
43
|
+
function TimeSyncService.Init(self: TimeSyncService)
|
|
44
|
+
assert(not (self :: any)._clockPromise, "TimeSyncService is already initialized!")
|
|
33
45
|
|
|
34
46
|
self._maid = Maid.new()
|
|
35
|
-
|
|
36
47
|
self._clockPromise = self._maid:Add(Promise.new())
|
|
37
48
|
|
|
38
49
|
if not RunService:IsRunning() then
|
|
@@ -55,7 +66,7 @@ end
|
|
|
55
66
|
|
|
56
67
|
@return boolean
|
|
57
68
|
]=]
|
|
58
|
-
function TimeSyncService
|
|
69
|
+
function TimeSyncService.IsSynced(self: TimeSyncService): boolean
|
|
59
70
|
if not RunService:IsRunning() then
|
|
60
71
|
return true
|
|
61
72
|
end
|
|
@@ -70,7 +81,7 @@ end
|
|
|
70
81
|
@yields
|
|
71
82
|
@return MasterClock | SlaveClock
|
|
72
83
|
]=]
|
|
73
|
-
function TimeSyncService
|
|
84
|
+
function TimeSyncService.WaitForSyncedClock(self: TimeSyncService): SyncedClock
|
|
74
85
|
if not RunService:IsRunning() then
|
|
75
86
|
return self:_buildMockClock()
|
|
76
87
|
end
|
|
@@ -84,7 +95,7 @@ end
|
|
|
84
95
|
|
|
85
96
|
@return MasterClock | SlaveClock | nil
|
|
86
97
|
]=]
|
|
87
|
-
function TimeSyncService
|
|
98
|
+
function TimeSyncService.GetSyncedClock(self: TimeSyncService): SyncedClock?
|
|
88
99
|
if not RunService:IsRunning() then
|
|
89
100
|
return self:_buildMockClock()
|
|
90
101
|
end
|
|
@@ -102,7 +113,7 @@ end
|
|
|
102
113
|
|
|
103
114
|
@return Promise<MasterClock | SlaveClock>
|
|
104
115
|
]=]
|
|
105
|
-
function TimeSyncService
|
|
116
|
+
function TimeSyncService.PromiseSyncedClock(self: TimeSyncService): Promise.Promise<SyncedClock>
|
|
106
117
|
if not RunService:IsRunning() then
|
|
107
118
|
return Promise.resolved(self:_buildMockClock())
|
|
108
119
|
end
|
|
@@ -111,11 +122,11 @@ function TimeSyncService:PromiseSyncedClock()
|
|
|
111
122
|
return Promise.resolved(self._clockPromise)
|
|
112
123
|
end
|
|
113
124
|
|
|
114
|
-
function TimeSyncService
|
|
115
|
-
return Rx.fromPromise(self:PromiseSyncedClock())
|
|
125
|
+
function TimeSyncService.ObserveSyncedClock(self: TimeSyncService): _Observable.Observable<SyncedClock>
|
|
126
|
+
return Rx.fromPromise(self:PromiseSyncedClock()) :: any
|
|
116
127
|
end
|
|
117
128
|
|
|
118
|
-
function TimeSyncService
|
|
129
|
+
function TimeSyncService._buildMockClock(_self: TimeSyncService): any
|
|
119
130
|
local mock = {}
|
|
120
131
|
|
|
121
132
|
function mock.IsSynced(_self)
|
|
@@ -133,7 +144,7 @@ function TimeSyncService:_buildMockClock()
|
|
|
133
144
|
return mock
|
|
134
145
|
end
|
|
135
146
|
|
|
136
|
-
function TimeSyncService
|
|
147
|
+
function TimeSyncService._buildMasterClock(self: TimeSyncService): MasterClock.MasterClock
|
|
137
148
|
local remoteEvent = GetRemoteEvent(TimeSyncConstants.REMOTE_EVENT_NAME)
|
|
138
149
|
local remoteFunction = GetRemoteFunction(TimeSyncConstants.REMOTE_FUNCTION_NAME)
|
|
139
150
|
|
|
@@ -142,21 +153,23 @@ function TimeSyncService:_buildMasterClock()
|
|
|
142
153
|
return clock
|
|
143
154
|
end
|
|
144
155
|
|
|
145
|
-
function TimeSyncService
|
|
146
|
-
return self._maid
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
156
|
+
function TimeSyncService._promiseSlaveClock(self: TimeSyncService): Promise.Promise<SlaveClock.SlaveClock>
|
|
157
|
+
return self._maid
|
|
158
|
+
:GivePromise(PromiseUtils.all({
|
|
159
|
+
PromiseGetRemoteEvent(TimeSyncConstants.REMOTE_EVENT_NAME),
|
|
160
|
+
PromiseGetRemoteFunction(TimeSyncConstants.REMOTE_FUNCTION_NAME),
|
|
161
|
+
}))
|
|
162
|
+
:Then(function(remoteEvent, remoteFunction)
|
|
163
|
+
local clock = self._maid:Add(SlaveClock.new(remoteEvent, remoteFunction))
|
|
164
|
+
|
|
165
|
+
return TimeSyncUtils.promiseClockSynced(clock)
|
|
166
|
+
end)
|
|
154
167
|
end
|
|
155
168
|
|
|
156
169
|
--[=[
|
|
157
170
|
Cleans up the time syncronization service.
|
|
158
171
|
]=]
|
|
159
|
-
function TimeSyncService
|
|
172
|
+
function TimeSyncService.Destroy(self: TimeSyncService)
|
|
160
173
|
self._maid:DoCleaning()
|
|
161
174
|
end
|
|
162
175
|
|