Skip to content

Commit 4cf8990

Browse files
committed
Merge gmod client part with the main client file
1 parent cced971 commit 4cf8990

File tree

2 files changed

+68
-84
lines changed

2 files changed

+68
-84
lines changed

examples/garrysmod-client.lua

Lines changed: 0 additions & 65 deletions
This file was deleted.

lua/long-polling/client.lua

Lines changed: 68 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
-- source: https://github.com/TRIGONIM/lua-long-polling/blob/e28fff8141c7d1a22e030c9d6132ef853032da84/lua/long-polling/client.lua
12
-- local kupol = require("long-polling.client")
2-
-- local client = kupol.new("https://lp.example.com/channel")
3+
-- local Client = kupol.new("https://lp.example.com/channel")
34
-- By default, client use copas and lua-cjson, but you can use your own functions
4-
-- See how to use it in Garry's Mod (without copas and cjson) in examples/
5+
-- from Garry's Mod for example
56

67
local kupol = {}
78

@@ -21,8 +22,8 @@ function MT:publish(tData)
2122
return code == 201 or res == "OK", code
2223
end
2324

24-
function MT:get(last_id, timeout)
25-
local paramstr = "?ts=" .. (last_id or "") .. "&sleep=" .. (timeout or "")
25+
function MT:get(offset, timeout)
26+
local paramstr = "?ts=" .. (offset or "") .. "&sleep=" .. (timeout or "")
2627

2728
local body, code_or_err = kupol.http_get(self.url .. paramstr)
2829
if not body then return false, code_or_err end
@@ -40,23 +41,30 @@ function MT:handle_error(err)
4041
self:log("🆘 Error\n\t%s", err)
4142
end
4243

43-
function MT:subscribe(fHandler, last_id, timeout)
44-
kupol.thread_new(function() while true do
45-
local to = last_id and timeout or 0 -- it's better if first request will be fast if last_id not provided
46-
local tData, body = self:get(last_id, to)
44+
function MT:subscribe(fHandler, requested_ts, timeout)
45+
self.thread = kupol.thread_new(function() repeat
46+
local tmt = requested_ts and timeout or 0 -- it's better if first request will be fast if requested_ts not provided
47+
local tData, body = self:get(requested_ts, tmt)
4748
if tData then
48-
if (last_id or 0) > tData.ts then
49-
self:log("🚧 ts on server is less than requested (%d < %d)", tData.ts, last_id)
50-
end
49+
local ts_diff = tData.ts - (requested_ts or 0)
50+
51+
local REM = (requested_ts or 0) > tData.ts -- REMOTE FUCKUP. e.g. remote ts 0, local ts 1000
52+
local LOC = ts_diff > #tData.updates -- LOCAL FUCKUP. e.g. remote ts 100, local ts 0, but 30 updates instead of 100
53+
if REM or LOC then
54+
if REM then
55+
self:log("🚧 ts on server is less than requested (%d < %d)", tData.ts, requested_ts)
56+
end
57+
58+
if LOC then
59+
self:log("🚧 updates lost: %d (got %d, expected %d)", ts_diff - #tData.updates, #tData.updates, ts_diff) -- too long time haven't requested them
60+
end
5161

52-
local updates_should_be = tData.ts - (last_id or 0)
53-
if updates_should_be > #tData.updates then
54-
local updates_lost = updates_should_be - #tData.updates
55-
self:log("🚧 updates lost: %d (got %d, expected %d)", updates_lost, #tData.updates, updates_should_be) -- too long haven't requested them
62+
requested_ts = tData.ts -- emerg reset
63+
else
64+
requested_ts = requested_ts and (requested_ts + #tData.updates) or tData.ts
65+
-- requested_ts = tData.ts
5666
end
5767

58-
-- last_id = last_id and (last_id + #tData.updates) or tData.ts
59-
last_id = tData.ts
6068
for _, update in ipairs(tData.updates) do
6169
local pcallok, res = pcall(fHandler, update, tData.ts)
6270
if not pcallok then
@@ -67,9 +75,11 @@ function MT:subscribe(fHandler, last_id, timeout)
6775
self:handle_error(body)
6876
kupol.thread_pause(10)
6977
end
70-
end end) -- while true, thread
78+
until (not self.thread) end)
7179
end
7280

81+
local IS_GARRYSMOD = (GM or GAMEMODE) and RunString and hook
82+
7383
local copas_ok, copas = pcall(require, "copas") -- should be loaded before http_v2
7484
if copas_ok then
7585
local http = require("http_v2") -- https://github.com/TRIGONIM/lua-requests-async/blob/main/lua/http_v2.lua
@@ -87,15 +97,54 @@ if copas_ok then
8797

8898
kupol.thread_new = copas.addthread
8999
kupol.thread_pause = copas.sleep
100+
101+
elseif IS_GARRYSMOD then
102+
function kupol.thread_new(f, ...)
103+
local co = coroutine.create(f)
104+
local function cont(...)
105+
local ok, callback = coroutine.resume(co, ...)
106+
if not ok then error( debug.traceback(co, callback) ) end
107+
if coroutine.status(co) ~= "dead" then callback(cont) end
108+
end
109+
cont(...)
110+
return co
111+
end
112+
113+
function kupol.thread_pause(seconds)
114+
coroutine.yield(function(cont) timer.Simple(seconds, cont) end)
115+
end
116+
117+
function kupol.http_get(url)
118+
return coroutine.yield(function(cont)
119+
http.Fetch(url, function(body, _, _, code) cont(body, code) end,
120+
function(err) cont(false, err) end)
121+
end)
122+
end
123+
124+
function kupol.http_post(url, data)
125+
return coroutine.yield(function(cont)
126+
local ok = HTTP({ url = url, method = "POST",
127+
body = data, type = "application/json",
128+
success = function(code, body) cont(body, code) end,
129+
failed = function(err) cont(false, err) end
130+
})
131+
if not ok then cont(false, "HTTP() failed") end
132+
end)
133+
end
134+
90135
else
91-
-- e.g. in Garry's Mod
92136
print("Kupol: looks like copas is not installed. So you should provide own kupol.http_* and kupol.thread_* functions")
93137
end
94138

95139
local cjson_ok, cjson = pcall(require, "cjson.safe")
96140
if cjson_ok then
97141
kupol.json_encode = cjson.encode
98142
kupol.json_decode = cjson.decode
143+
144+
elseif IS_GARRYSMOD then
145+
kupol.json_encode = util.TableToJSON
146+
kupol.json_decode = util.JSONToTable
147+
99148
else
100149
print("Kupol: looks like lua-cjson is not installed. So you should provide own kupol.json_encode and kupol.json_decode functions")
101150
end

0 commit comments

Comments
 (0)