--local canPost = true local function onDispatcherMessage(msg) if string.sub(msg,1,1) == "@" then local cmd = string.Explode(",",string.sub(msg,2)) if cmd[1] == "red" then for k,v in pairs(Metrostroi.TrafficLights) do if v:IsValid() and (v.EquipmentID == tonumber(cmd[2])) then v.TelemetryOverrideToRed = true if Metrostroi.TrafficLightStates[v] then Metrostroi.TrafficLightStates[v].state = -1 end end end elseif cmd[1] == "auto" then for k,v in pairs(Metrostroi.TrafficLights) do if v:IsValid() and (v.EquipmentID == tonumber(cmd[2])) then v.TelemetryOverrideToRed = nil if Metrostroi.TrafficLightStates[v] then Metrostroi.TrafficLightStates[v].state = -1 end end end end print("Dispatcher command: "..msg) else PrintMessage(HUD_PRINTTALK,"Dispatcher: "..msg) print("Dispatcher: "..msg) Metrostroi.DriverChatBacklog["global"] = Metrostroi.DriverChatBacklog["global"] or {} table.insert(Metrostroi.DriverChatBacklog["global"],"Dispatcher: "..msg) end end local function onSuccess(content) local data = string.Explode("\n",content) if data[1] == "OK" then for i=2,#data do if data[i] and (data[i] ~= "") then onDispatcherMessage(data[i]) end end end -- print(content) end local function onFailure(reason) end -------------------------------------------------------------------------------- -- Sends asynchronous HTTP request -------------------------------------------------------------------------------- --timer.Simple(0.01, function() require("socket") end) local s local http_data function Metrostroi.HTTPRequest(request) if not socket then return end -- Process data -- print(string.gsub(data," ","+")) -- Re-create socket if s then s:close() end s = socket.connect("foxworks.wireos.com", 80) s:settimeout(0.00) -- s:send("GET /metrostroi/ms-act.php HTTP/1.1\n") s:send("POST /metrostroi/ms-act.php HTTP/1.0\n") s:send("Host: foxworks.wireos.com\n") s:send("User-Agent: GMod10\n") s:send("Connection: Close\n") s:send("Content-Type: application/x-www-form-urlencoded\n") s:send("Content-Length: "..#request.."\n") s:send("\n") s:send(request) http_data = "" -- Create timer timer.Create("Metrostroi_HTTPRequest",0.01,0,function() if not s then return end s:settimeout(0.00) local data, status, rdata = s:receive(2^10) data = data or rdata -- Gather HTTP data if data then http_data = http_data .. data end -- Check timeout/error if status and (status ~= "timeout") then local data = string.Explode("\r\n\r\n",http_data) table.remove(data,1) local content = table.concat(data,"\n\n") timer.Remove("Metrostroi_HTTPRequest") onSuccess(content) end end) end -------------------------------------------------------------------------------- -- Generate HTTP request -------------------------------------------------------------------------------- local function bool2str(b) if b then return "1" else return "0" end end Metrostroi.TrafficLightStates = {} Metrostroi.SwitchStates = {} function Metrostroi.UpdateTelemetry() if true then return end if not Metrostroi.TrainPositions then return end local request = "query=update&r={ \"trains\": {" local f = false for train,data in pairs(Metrostroi.TrainPositions) do if train:IsValid() and train.WagonID then if f == true then request = request.."," end if f == false then f = true end -- print(train.WagonID) request = request.."\""..train.WagonID.."\": {" request = request.."\"wid\":"..train.WagonID.."," request = request.."\"tid\":"..train.TrainID.."," request = request.."\"mod\":"..train.Mode.."," request = request.."\"pos\":"..Format("%.1f",data.position).."," request = request.."\"sec\":"..Format("%d", data.section).."," request = request.."\"pth\":"..Format("%d", data.path).."," if train.NextLightRed then request = request.."\"nxt\":1," elseif train.NextLightYellow then request = request.."\"nxt\":2," else request = request.."\"nxt\":3," end request = request.."\"spd\":"..Format("%.1f",train.Speed or 0).."," request = request.."\"ars\":"..Format("%.1f",train.ARSSpeed or -1).."," if train.Reverse then request = request.."\"d1\":"..bool2str(train.DoorState[1]).."," request = request.."\"d2\":"..bool2str(train.DoorState[0]).."," else request = request.."\"d1\":"..bool2str(train.DoorState[0]).."," request = request.."\"d2\":"..bool2str(train.DoorState[1]).."," end request = request.."\"l1\":"..bool2str(train.LightState[0]).."," request = request.."\"l2\":"..bool2str(train.LightState[1]).."," request = request.."\"r\":"..bool2str(train.Reverse).."," request = request.."\"m\":"..bool2str(train.MasterTrain == nil).."," request = request.."\"at\":"..bool2str(train.AlternateTrack).."," request = request.."\"sat\":"..bool2str(train.SelectAlternateTrack).."," request = request.."\"atb\":"..bool2str(train.AlternateTrackBlocked) --[[Metrostroi.DriverChatBacklog[train] = Metrostroi.DriverChatBacklog[train] or {} local chatlog = "{" for k,v in pairs(Metrostroi.DriverChatBacklog[train]) do chatlog = chatlog.."\""..k.."\":".."\""..v.."\"" if k ~= #Metrostroi.DriverChatBacklog[train] then chatlog = chatlog.."," end end Metrostroi.DriverChatBacklog[train] = {} request = request.."\"log\":"..chatlog.."}" ]]-- request = request.."}" end end request = request.."}," request = request.."\"chat\":{" local i = 1 local f = false for train,data in pairs(Metrostroi.DriverChatBacklog) do if (train ~= "global") and train:IsValid() then for k,v in pairs(data) do if f == true then request = request.."," end f = true request = request.."\""..i.."\":{" request = request.."\"t\":".."\""..v.."\"," request = request.."\"w\":".."\""..train.WagonID.."\"" request = request.."}" i = i + 1 end Metrostroi.DriverChatBacklog[train] = {} else for k,v in pairs(data) do if f == true then request = request.."," end f = true request = request.."\""..i.."\":{" request = request.."\"t\":".."\""..v.."\"," request = request.."\"w\":".."\"global\"" request = request.."}" i = i + 1 end Metrostroi.DriverChatBacklog[train] = {} end end request = request.."}," request = request.."\"lights\":{" local f = false for light,data in pairs(Metrostroi.TrafficLightPositions) do if light:IsValid() and light.EquipmentID then local bits = 0 if light.LightStates[1] then bits = bits + 1 end if light.LightStates[2] then bits = bits + 2 end if light.LightStates[3] then bits = bits + 4 end if (not Metrostroi.TrafficLightStates[light]) or (Metrostroi.TrafficLightStates[light].state ~= bits) or (CurTime() - Metrostroi.TrafficLightStates[light].time > 120) then if f == true then request = request.."," end f = true Metrostroi.TrafficLightStates[light] = { state = bits, time = CurTime(), } request = request.."\""..light.EquipmentID.."\": {" request = request.."\"id\":"..light.EquipmentID.."," request = request.."\"state\":"..bits.."," request = request.."\"ovrd\":"..bool2str(light.TelemetryOverrideToRed).."," request = request.."\"pos\":"..Format("%.1f",data.position).."," request = request.."\"pth\":"..Format("%d", data.path).."," request = request.."\"fwd\":"..bool2str(data.forward_facing).."," request = request.."\"lgh\":\""..string.lower(light.TrafficLight).."\" " request = request.."}" end end end --[[request = request.."\"switches\":{" local f = false for index,switch in pairs(Metrostroi.PicketSignByIndex) do if switch:IsValid() and switch.TrackSwitchName then local state = switch:GetTrackSwitchState() if (not Metrostroi.SwitchStates[switch]) or (Metrostroi.SwitchStates[switch].state ~= bits) or (CurTime() - Metrostroi.SwitchStates[switch].time > 120) then if f == true then request = request.."," end f = true Metrostroi.SwitchStates[switch] = { state = state, time = CurTime(), } request = request.."\""..index.."\": {" request = request.."\"id\":"..index.."," request = request.."\"state\":"..bool2str(state) request = request.."}" end end end]]-- request = request.."}}" Metrostroi.HTTPRequest(request) -- print(request) -- http.Post("http://foxworks.wireos.com/metrostroi/ms-act.php",{ r = request, query = "update" },onSuccess,onFailure) -- print("POST",CurTime()) end timer.Create("Metrostroi_UpdateTelemetry",1.0,0,Metrostroi.UpdateTelemetry) -------------------------------------------------------------------------------- -- Get driver chats -------------------------------------------------------------------------------- if not Metrostroi.DriverChatBacklog then Metrostroi.DriverChatBacklog = {} end --[[hook.Add("PlayerSay", "Metrostroi_PlayerSay", function(ply,text,team) local name = ply:GetName() local trains = ents.FindInSphere(ply:GetPos(),768) --512) local train = nil for k,v in pairs(trains) do if v.IsSubwayTrain then train = v end end if not train then local trains = ents.FindByClass("gmod_subway_81-717") if trains[1] then train = trains[1] end name = name.."[a]" end if train then Metrostroi.DriverChatBacklog[train] = Metrostroi.DriverChatBacklog[train] or {} table.insert(Metrostroi.DriverChatBacklog[train],name..": "..text) end return text end)]]--