Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Lanes
- --[[
- Documenation:
- This script will allow you to easily execute any non-Phasor function in Lua lanes.
- Lanes allow you to execute multiple chunks of code at once, which will ultimately solve all lag issues with functions that require a lot of power.
- In order for this to work, you MUST specify all functions and global variables lanes will be using in the 'global' table (see below).
- There are only a few functions and they are all specifically made to be straightforward and easier to use than lanes by itself.
- The examples given in each of the function descriptions will build a script that will request a player's stats from a website and write to them in the script.
- thread.execute(func, ...)
- -- func: <string> The name of the function you want to be executed in a separate thread.
- -- ...: <any amount of data> The parameters that should be passed into the function you're calling in a separate thread.
- Returns: Key which will be used for retrieving returned data.
- Example:
- global = {"getstats"}
- URL = "http://www.phasorstats.com/examplestats" -- not a real URL; just used for the sake of example
- function OnPlayerJoin(player)
- local hash = gethash(player)
- local key = thread.execute("getstats", hash)
- end
- function getstats(hash)
- local http = require "socket.http"
- local info = http.request(URL .. "/" .. hash) -- pretending that the stats are stored at "http://www.phasorstats.com/examplestats/" .. hash
- return assert(load(info))() -- assuming the data is sent from the website in the same form as table.save saves tables
- end
- Notes:
- -- Make sure all functions you use in thread.execute are in the global table, including functions called within the functions you use in thread.execute.
- -- Once again, Phasor functions DO NOT WORK in separate threads, so make sure the function you are passing has no Phasor functions.
- thread.receive(key)
- -- key: <string> Key returned by thread.execute to access the return value of the function call.
- Returns: What is returned by the function passed into thread.execute at the specified key.
- Example:
- global = {"http", "getstats"}
- URL = "http://www.phasorstats.com/examplestats" -- not a real URL; just used for the sake of example
- function OnPlayerJoin(player)
- local hash = gethash(player)
- local key = thread.execute("getstats", hash)
- registertimer(100, "ReceiveStats", {player, key}) -- we need to register a timer that will check to see when the thread finishes executing and has a response.
- end
- function ReceiveStats(id, count, info)
- local player, key = table.unpack(info)
- if thread.done(key) then -- thread.done example (see thread.done syntax for info)
- local hash = gethash(player)
- stats[hash] = thread.receive(key) -- set the player's stats to what getstats returns
- return false -- no need to keep this timer running
- end
- return true -- keep calling the timer until getstats is finished executing
- end
- function getstats(hash)
- local http = require "socket.http"
- local info = http.request(URL .. "/" .. hash) -- pretending that the stats are stored at "http://www.phasorstats.com/examplestats/" .. hash
- return assert(load(info))() -- assuming the data is sent from the website in the same form as table.save saves tables
- end
- thread.done(key)
- -- key: <string> Key returned by thread.execute.
- Returns: Boolean specifying if the thread has finished (true or false).
- Example:
- (See example for thread.receive)
- thread.cancel(key)
- -- key: <string> Key returned by thread.execute.
- Example:
- statsthread = {}
- global = {"http", "getstats"}
- URL = "http://www.phasorstats.com/examplestats" -- not a real URL; just used for the sake of example
- function OnPlayerJoin(player)
- local hash = gethash(player)
- local key = thread.execute("getstats", hash)
- statsthread[player] = key
- registertimer(100, "ReceiveStats", {player, key}) -- we need to register a timer that will check to see when the thread finishes executing and has a response.
- end
- function OnPlayerLeave(player)
- thread.cancel(statsthread[player])
- end
- function ReceiveStats(id, count, info)
- local player, key = table.unpack(info)
- if thread.done(key) then -- thread.done example (see thread.done syntax for info)
- local hash = gethash(player)
- stats[hash] = thread.receive(key) -- set the player's stats to what getstats returns
- return false -- no need to keep this timer running
- end
- return true -- keep calling the timer until getstats is finished executing
- end
- function getstats(hash)
- local http = require "socket.http"
- local info = http.request(URL .. "/" .. hash) -- pretending that the stats are stored at "http://www.phasorstats.com/examplestats/" .. hash
- return assert(load(info))() -- assuming the data is sent from the website in the same form as table.save saves tables
- end
- Notes:
- -- This is only necessary if you want to stop a thread from attempting to execute a function.
- -- In the case of our stats example, we want to cancel the thread from executing if the player leaves before we can access his/her stats.
- -- Using thread.cancel on a key that has already finished executing has no effect.
- Miscellaneous Notes:
- -- Make sure functions you execute in separate threads don't have random number calculations in them; they will probably always end up being the same.
- -- If you are using other libraries (like socket), make sure you require them in the function they're being used in (see thread.execute example).
- If you have any questions about this script, PM me (Nuggets) at phasor.proboards.com.
- --]]
- -- The Global Table --
- -- Insert the names of user-created (i.e. not string.gsub, table.len, etc.) variables as strings which will be used in lanes, including functions used in functions you specify.
- -- For example, if your function called "somefunction" uses a function within it called "anotherfunction", you must also include "anotherfunction" for "somefunction" to work.
- -- You may not use Phasor functions (you will get a Lua Lanes error).
- global = {"getlanguage", "translate", "string.split"}
- -- Don't edit below this line --
- local lanes = require "lanes"
- lanes.configure()
- local linda = lanes.linda()
- lua_lanes_error = false
- thread = {}
- function GetRequiredVersion()
- return 200
- end
- function OnScriptLoad(processId, game, persistent)
- laneglobals = GetGlobalTable()
- workerhandle = lanes.gen("*", {globals = laneglobals}, Worker)
- registertimer(100, "ErrorCheck")
- registertimer(10, "Sender")
- registertimer(10, "Receiver")
- end
- function GetGlobalTable()
- funcs = {}
- for _,func in ipairs(global) do
- local split = string.split(func, ".")
- local f = "funcs"
- local g = "_G"
- for k,v in ipairs(split) do
- if type(v) == "string" then
- v = "\"" .. v .. "\""
- end
- f = f .. "[" .. v .. "]"
- g = g .. "[" .. v .. "]"
- assert(load(f .. " = " .. f .. " or " .. g .. " or {}"))()
- end
- assert(load(f .. " = " .. g))()
- end
- return funcs
- end
- function Worker(key)
- while true do
- local _,cmd = linda:receive("command: " .. key)
- local _,parameters = linda:receive("parameters: " .. key)
- if cmd == "thread.cancel" then
- linda:send("returnthread.cancel" .. key)
- break
- else
- if _G[cmd] then
- local v = {_G[cmd](table.unpack(parameters))}
- linda:send("return " .. key, v)
- else
- print("Warning: " .. cmd .. " not defined in global table!")
- print("Execution of " .. cmd .. " has been cancelled.")
- end
- break
- end
- end
- end
- function Sender(id, count)
- for k,v in pairs(thread) do
- if type(v) == "table" then
- if not thread[k].sent then
- thread[k].sent = true
- thread[k].handle = workerhandle(k)
- end
- end
- end
- return not lua_lanes_error
- end
- function Receiver(id, count)
- for k,v in pairs(thread) do
- if type(v) == "table" then
- if not thread[k].done then
- _,thread[k].value = linda:receive(0, "return " .. k)
- if thread[k].value then
- thread[k].done = true
- thread[k].handle = nil
- end
- end
- end
- end
- return not lua_lanes_error
- end
- function ErrorCheck(id, count)
- for k,v in pairs(thread) do
- if type(v) == "table" then
- local worker = thread[k].handle
- if worker then
- if worker.status == "error" then
- hprintf("Lua Lanes Error:")
- _, err = worker:join()
- hprintf(err)
- lua_lanes_error = true
- return false
- end
- end
- end
- end
- return true
- end
- function thread.execute(func, ...)
- local args = {...}
- for k,v in ipairs(args) do
- args[k] = tostring(v)
- end
- local key = func .. table.concat(args, "")
- if not thread[key] then
- linda:send("command: " .. key, func)
- linda:send("parameters: " .. key, {...})
- thread[key] = {}
- end
- return key
- end
- function thread.receive(key)
- return table.unpack(thread[key].value)
- end
- function thread.done(key)
- return thread[key].done or false
- end
- function thread.cancel(key)
- thread.execute("thread.cancel", key)
- local worker = thread[key].handle
- if worker then
- while worker.status == "running" or worker.status == "waiting" do end
- end
- end
- function getlanguage(message)
- local http = require "socket.http"
- print("Requesting language...")
- local info = http.request("http://ws.detectlanguage.com/0.2/detect?q=" .. message .. "&key=95a28db284849a58d0b1b60909cfd684")
- local language = string.gsub(string.split(info, '"language":', ',"isReliable:"')[2] or "en", '"', "")
- print("Done.")
- return language
- end
- function translate(from, to, message)
- local http = require "socket.http"
- print("Requesting translation...")
- local info = http.request("http://syslang.com/?src=" .. from .. "&dest=" .. to .. "&text=" .. message .. "&[email protected]&password=cheese&outformat=json")
- local translation = string.gsub(string.split(info, '"translation":', ',"action"')[2], '"', "")
- print("Done.")
- return translation
- end
- function OnScriptUnload()
- for k,v in pairs(thread) do
- if type(v) == "table" then
- thread.cancel(k)
- end
- end
- end
- --[[
- function OnNewGame(map)
- end
- --]]
- --[[
- function OnGameEnd(stage)
- -- stage 1: F1 Screen
- -- stage 2: PGCR Appears
- -- stage 3: Players may quit
- end
- --]]
- function OnServerChat(player, type, message)
- if player and type < 4 then
- message = string.gsub(message, " ", "+")
- for i = 0,15 do
- if getplayer(i) then
- registertimer(100, "Translate", {player, i, message})
- end
- end
- return false
- end
- end
- function Translate(id, count, info)
- local sending, receiving, message = table.unpack(info)
- local langkey = thread.execute("getlanguage", message)
- if thread.done(langkey) then
- local native = "es" -- would actually get receiver's native language here
- local transkey = thread.execute("translate", thread.receive(langkey), native, message)
- if thread.done(transkey) then
- privatesay(receiving, getname(sending) .. ": " .. thread.receive(transkey), false)
- return false
- end
- end
- return true
- end
- --[[
- function OnServerCommandAttempt(player, command, password)
- --return true
- end
- --]]
- --[[
- function OnServerCommand(admin, command)
- --return true
- end
- --]]
- --[[
- function OnNameRequest(hash, name)
- --return true, name
- end
- --]]
- --[[
- function OnBanCheck(hash, ip)
- --return true
- end
- --]]
- --[[
- function OnPlayerJoin(player)
- end
- --]]
- --[[
- function OnPlayerLeave(player)
- end
- --]]
- --[[
- function OnPlayerKill(killer, victim, mode)
- -- mode 0: Killed by server
- -- mode 1: Killed by fall damage
- -- mode 2: Killed by guardians
- -- mode 3: Killed by vehicle
- -- mode 4: Killed by killer
- -- mode 5: Betrayed by killer
- -- mode 6: Suicide
- end
- --]]
- --[[
- function OnKillMultiplier(player, multiplier)
- -- Multipliers:
- -- 7: Double Kill
- -- 9: Triple Kill
- -- 10: Killtacular
- -- 11: Killing Spree
- -- 12: Running Riot
- -- 16: Double Kill w/ Score
- -- 17: Triple Kill w/ Score
- -- 14: Killtacular w/ Score
- -- 18: Killing Spree w/ Score
- -- 17: Running Riot w/ Score
- end
- --]]
- --[[
- function OnPlayerSpawn(player)
- end
- --]]
- --[[
- function OnPlayerSpawnEnd(player)
- end
- --]]
- --[[
- function OnWeaponAssignment(player, objId, slot, weapId)
- --return mapId
- end
- --]]
- --[[
- function OnWeaponReload(player, weapId)
- --return true
- end
- --]]
- --[[
- function OnObjectCreationAttempt(mapId, parentId, player)
- --return mapId
- end
- --]]
- --[[
- function OnObjectCreation(objId)
- end
- --]]
- --[[
- function OnObjectInteraction(player, objId, mapId)
- end
- --]]
- --[[
- function OnTeamDecision(team)
- --return team
- end
- --]]
- --[[
- function OnTeamChange(player, old_team, new_team, voluntary)
- --return true
- end
- --]]
- --[[
- function OnDamageLookup(receiver, causer, mapId)
- --return true
- end
- --]]
- --[[
- function OnDamageApplication(receiver, causer, mapId, location, backtap)
- --return true
- end
- --]]
- --[[
- function OnVehicleEntry(player, vehiId, seat, mapId, voluntary)
- --return true
- end
- --]]
- --[[
- function OnVehicleEject(player, voluntary)
- --return true
- end
- --]]
- --[[
- function OnClientUpdate(player)
- end
- --]]
- function string.split(str, ...)
- local args = {...}
- for k,v in ipairs(args) do
- if v == "" then
- local subs = {}
- for i = 1,string.len(str) do
- table.insert(subs, string.sub(str, i, i))
- end
- return subs
- end
- end
- local subs = {}
- local sub = ""
- for i = 1,string.len(str) do
- local bool
- local char = string.sub(str, i, i)
- for k,v in ipairs(args) do
- local delim = string.sub(str, i - (string.len(v) - 1), i)
- if v == delim then
- bool = true
- sub = string.sub(sub, 1, string.len(sub) - (string.len(v) - 1))
- if sub ~= "" then
- table.insert(subs, sub)
- end
- sub = ""
- break
- end
- end
- if not bool then
- sub = sub .. char
- end
- if i == string.len(str) then
- table.insert(subs, sub)
- end
- end
- return subs
- end
Add Comment
Please, Sign In to add comment