mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2026-11-13 16:14:52 +09:00
Added module: ExpGamingCore.Commands
This commit is contained in:
1 parent
6272e29606
commit
9be85f04a6
31 files changed
+686
-289
No files matched your search
@@ -1,74 +1,139 @@
|
||||
--[[
|
||||
Explosive Gaming
|
||||
--- A full ranking system for factorio.
|
||||
-- @module ExpGamingCore.Commands
|
||||
-- @alias commands
|
||||
-- @author Cooldude2606
|
||||
-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE
|
||||
|
||||
This file can be used with permission but this and the credit below must remain in the file.
|
||||
Contact a member of management on our discord to seek permission to use our code.
|
||||
Any changes that you may make to the code are yours but that does not make the script yours.
|
||||
Discord: https://discord.gg/r6dC2uK
|
||||
]]
|
||||
--Please Only Edit Below This Line-----------------------------------------------------------
|
||||
local command_calls = {}
|
||||
local command_data = {}
|
||||
--- Used as an error constant for validation
|
||||
-- @field commands.error
|
||||
-- @usage return commands.error, 'err message'
|
||||
-- @usage return commands.error('err message')
|
||||
commands.error = setmetatable({},{__call=function(...) return ... end})
|
||||
commands._add_command = commands.add_command
|
||||
local data = {}
|
||||
|
||||
--- Uses a commands data to return the inputs as a string
|
||||
-- @usage command = command_data[command_name]
|
||||
-- command_inputs(command) -- returns "<input1> <input2> "
|
||||
-- @tparam table the data for the command being run
|
||||
-- @treturn string the inputs in string format
|
||||
local function command_inputs(command)
|
||||
if not is_type(command,'table') then return end
|
||||
local inputs = ''
|
||||
for _,input in pairs(command.inputs) do
|
||||
if input == true then break end
|
||||
inputs = inputs..'<'..input..'> '
|
||||
--- Index of all command data
|
||||
-- @field commands.data
|
||||
-- @usage commands.command_name -- returns command data
|
||||
-- @usage commands.data -- returns all data
|
||||
-- @tparam ?string|table|event key the command that will be returned: string is the name, table is the command data, event is event from add_command
|
||||
-- @treturn table the command data
|
||||
setmetatable(commands,{
|
||||
__index=function(tbl,key) return is_type(key,'table') and (key.command and rawget(data,key.name) or key) or key == 'data' and data or rawget(data,key) end
|
||||
})
|
||||
|
||||
--- Collection of funcations that can be used to validate inputs
|
||||
-- @table commands.validate
|
||||
-- @usage commands.validate[type](value,event,...)
|
||||
-- @tparam string type the type that the value should be
|
||||
-- @param value the value that will be tested
|
||||
-- @param ... any other data that can be passed to the function
|
||||
-- @return[1] the validated value
|
||||
-- @return[2] error constant
|
||||
-- @return[2] the err message
|
||||
-- @field __comment replace _ with - the ldoc did not like me using - in the names
|
||||
-- @field string basicly does nothing but a type filed is required
|
||||
-- @field string_inf same as string but is infite in length, must be last arg
|
||||
-- @field string_len same as string but can define a max lengh
|
||||
-- @field number converts the input into a number
|
||||
-- @field number_int conerts the input to a number and floors it
|
||||
-- @field number_range allows a number in a range min < X <= max
|
||||
-- @field number_range allows a number in a range after it has been floored min < math.floor(X) <= max
|
||||
-- @field player converts the input into a valid player
|
||||
-- @field player_online converts the input to a player if the player is online
|
||||
-- @field player_alive converts the input to a player if the player is online and alive
|
||||
-- @field player_rank converts the input to a player if the player is a lower rank than the user
|
||||
-- @field player_rank-online converts the input to a player if the player is a lower rank than the user and online
|
||||
-- @field player_rank_alive converts the input to a player if the player is a lower rank than the user and online and alive
|
||||
commands.validate = {
|
||||
['string']=function(value,event) return tostring(value) end,
|
||||
['string-inf']=function(value,event) return tostring(value) end,
|
||||
['string-len']=function(value,event,max) return tostring(value) and tostring(value):len() <= max and tostring(value) or commands.error{'commands.error-string-len'} end,
|
||||
['number']=function(value,event) return tonumber(value) or commands.error{'commands.error-number'} end,
|
||||
['number-int']=function(value,event) return tonumber(value) and math.floor(tonumber(value)) or commands.error{'commands.error-number'} end,
|
||||
['number-range']=function(value,event,min,max) return tonumber(value) and tonumber(value) > min and tonumber(value) <= max and tonumber(value) or commands.error{'commands.error-number-range'} end,
|
||||
['number-range-int']=function(value,event,min,max) return tonumber(value) and math.floor(tonumber(value)) > min and math.floor(tonumber(value)) <= max and math.floor(tonumber(value)) or commands.error{'commands.error-number-range'} end,
|
||||
['player']=function(value,event) return Game.get_player(player) or commands.error{'commands.error-player'} end,
|
||||
['player-online']=function(value,event) local player,err = commands.validate['player'](value) return err and commands.error(err) or player.conected and player or commands.error{'commands.error-player-online'} end,
|
||||
['player-alive']=function(value,event) local player,err = commands.validate['player-online'](value) return err and commands.error(err) or player.character and player.character.health > 0 and player or commands.error{'commands.error-player-alive'} end,
|
||||
['player-rank']=function(value,event) local player,err = commands.validate['player'](value) return err and commands.error(err) or Ranking and Ranking.get_rank(player).power > Ranking.get_rank(event).power or not player.admin or commands.error{'commands.error-player-rank'} end,
|
||||
['player-rank-online']=function(value,event) local player,err = commands.validate['player-online'](value) return err and commands.error(err) or Ranking and Ranking.get_rank(player).power > Ranking.get_rank(event).power or not player.admin or commands.error{'commands.error-player-rank'} end,
|
||||
['player-rank-alive']=function(value,event) local player,err = commands.validate['player-alive'](value) return err and commands.error(err) or Ranking and Ranking.get_rank(player).power > Ranking.get_rank(event).power or not player.admin or commands.error{'commands.error-player-rank'} end
|
||||
}
|
||||
|
||||
--- Returns the inputs of this command as a formated string
|
||||
-- @usage commands.format_inputs('interface') -- returns <code> (if you have ExpGamingCore.Server)
|
||||
-- @tparam ?string|table|event command the command to get the inputs of
|
||||
-- @treturn string the formated string for the inputs
|
||||
function commands.format_inputs(command)
|
||||
local command = commands[command]
|
||||
if not is_type(command,'table') then error('Command is not valid',2) end
|
||||
local rtn = ''
|
||||
for name,data in pairs(command.inputs) do
|
||||
if data[1] == false then rtn=rtn..string.format('[%s] ',name)
|
||||
else rtn=rtn..string.format('<%s> ',name) end
|
||||
end
|
||||
return inputs
|
||||
return rtn
|
||||
end
|
||||
|
||||
--- Uses the command data and the event to return a table of the args
|
||||
-- @usage command = command_data[command_name]
|
||||
-- command_args(event,command) -- return {input1='one',input2='two'}
|
||||
-- @tparam defines.events.on_console_command event the event rasied by the command
|
||||
-- @tparam table command the data for the command being run
|
||||
-- @treturn table a table version of the event.parameter based on expected inputs
|
||||
local function command_args(event,command)
|
||||
if not event or not is_type(command,'table') then return end
|
||||
local args = {}
|
||||
-- haddles no parameters given
|
||||
--- Used to validate the arguments of a command, will understand strings with "" as a single param else spaces divede the params
|
||||
-- @usage commands.validate_args(event) -- returns args table
|
||||
-- @tparam table event this is the event created by add_command not on_console_command
|
||||
-- @treturn[1] table the args for this command
|
||||
-- @return[2] command.error
|
||||
-- @treturn string the error that happend while parsing the args
|
||||
function commands.validate_args(event)
|
||||
local command = commands[event.name]
|
||||
if not is_type(command,'table') then error('Command not valid',2) end
|
||||
local rtn = {}
|
||||
local count = 0
|
||||
local count_opt = 0
|
||||
for name,data in pairs(command.inputs) do count = count + 1 if data[1] == false then count_opt = count_opt + 1 end end
|
||||
-- checks that there is some args given if there is ment to be
|
||||
if not event.parameter then
|
||||
if #command.inputs > 0 then return args, false
|
||||
else return args, true
|
||||
end
|
||||
if count == count_opt then return rtn
|
||||
else return commands.error('invalid-inputs') end
|
||||
end
|
||||
-- finds all the words and cheaks if the right number were given
|
||||
-- splits the args into words so that it can be used to asign values
|
||||
local words = string.split(event.parameter,' ')
|
||||
if table.last(command.inputs) == true then
|
||||
if #words < #command.inputs-1 then return args, false end
|
||||
else
|
||||
if #words < #command.inputs then return args, false end
|
||||
end
|
||||
-- if it is the right number then process and return the args
|
||||
for index,input in pairs(command.inputs) do
|
||||
if command.inputs[index+1] == true then
|
||||
args[input] = table.concat(words,' ',index)
|
||||
break
|
||||
else
|
||||
args[input] = words[index]
|
||||
local index = 0
|
||||
for _,word in pairs(words) do
|
||||
index = index+1
|
||||
if not word then break end
|
||||
local pos, _pos = word:find('"')
|
||||
while pos and pos == _pos do
|
||||
local next = table.remove(words,index+1)
|
||||
if not next then return commands.error('invalid-parse') end
|
||||
words[index] = words[index]..' '..next
|
||||
_pos = words[index]:find('"',pos+1)
|
||||
end
|
||||
end
|
||||
return args, true
|
||||
-- assigns the values from the words to the args
|
||||
local index = 0
|
||||
for name,data in pairs(command.inputs) do
|
||||
index = index+1
|
||||
local arg = words[index]
|
||||
if not arg and not data[1] then return commands.error('invalid-inputs') end
|
||||
if data[2] == 'string-inf' then rtn[name] = table.concat(words,' ',index) break end
|
||||
local valid = is_type(data[2],'function') and data[2] or commands.validate[data[2]] or error('Invalid type for command: "'..command.name..'/'..name..'"')
|
||||
local temp_tbl = table.deep_copy(data) table.remove(temp_tbl,1) table.remove(temp_tbl,2)
|
||||
local value, err = valid(arg,event,unpack(temp_tbl))
|
||||
if value == commands.error then return value, err end
|
||||
rtn[name] = value
|
||||
end
|
||||
return rtn
|
||||
end
|
||||
|
||||
--- Used to return all the commands a player can use
|
||||
-- @usage get_commands(1) -- return {{command data},{command data}}
|
||||
-- @param player the player refreced by string|number|LuaPlayer|event
|
||||
-- @usage get_commands(1) -- return table of command data for each command that the player can use
|
||||
-- @tparam ?index|name|player| player the player to test as
|
||||
-- @treturn table a table containg all the commands the player can use
|
||||
function commands.get_commands(player)
|
||||
local commands = {}
|
||||
local player = Game.get_player(player)
|
||||
if not player then return commands end
|
||||
if not player then return error('Invalid player',2) end
|
||||
local rank = Ranking.get_rank(player)
|
||||
for name,data in pairs(command_data) do
|
||||
for name,data in pairs(data) do
|
||||
if rank:allowed(name) then table.insert(commands,data) end
|
||||
end
|
||||
return commands
|
||||
@@ -76,27 +141,27 @@ end
|
||||
|
||||
--- Used to call the custom commands
|
||||
-- @usage You dont its an internal command
|
||||
-- @tparam defines.events.on_console_command command the event rasied by the command
|
||||
-- @tparam table command the event rasied by the command
|
||||
local function run_custom_command(command)
|
||||
local command_data = command_data[command.name]
|
||||
local data = commands.data[command.name]
|
||||
local player_name = Game.get_player(command) and Game.get_player(command).name or 'server'
|
||||
-- is the player allowed to use this command
|
||||
if is_type(Ranking,'table') and Ranking._presets and Ranking._presets().meta.rank_count > 0 and not Ranking.get_rank(player_name):allowed(command.name) then
|
||||
-- is the player allowed to use this command, if no ExpGamingCore.Ranking then this is ingroned
|
||||
if Ranking and Ranking.meta and Ranking.meta.rank_count > 0 and not Ranking.get_rank(player_name):allowed(command.name) then
|
||||
player_return({'commands.unauthorized'},defines.textcolor.crit)
|
||||
if game.player then game.player.play_sound{path='utility/cannot_build'} end
|
||||
game.write_file('commands.log',
|
||||
game.tick
|
||||
..' Player: "'..player_name..'"'
|
||||
..' Failed to use command (Unauthorized): "'..command.name..'"'
|
||||
..' With args of: '..table.tostring(command_args(command,command_data))
|
||||
..' With args of: '..table.tostring(commands.validate_args(command))
|
||||
..'\n'
|
||||
, true, 0)
|
||||
return
|
||||
end
|
||||
-- gets the args for the command
|
||||
local args, valid = command_args(command,command_data)
|
||||
if not valid then
|
||||
player_return({'commands.invalid-inputs',command.name,command_inputs(command_data)},defines.textcolor.high)
|
||||
local args, err = commands.validate_args(command)
|
||||
if args == commands.error then
|
||||
player_return({'commands.'..err,command.name,commands.format_inputs(data)},defines.textcolor.high)
|
||||
if game.player then game.player.play_sound{path='utility/deconstruct_big'} end
|
||||
game.write_file('commands.log',
|
||||
game.tick
|
||||
@@ -108,7 +173,7 @@ local function run_custom_command(command)
|
||||
return
|
||||
end
|
||||
-- runs the command
|
||||
local success, err = pcall(command_calls[command.name],command,args)
|
||||
local success, err = pcall(data.callback,command,args)
|
||||
if not success then error(err) end
|
||||
if err ~= commands.error and player_name ~= 'server' then player_return({'commands.command-ran'},defines.textcolor.info) end
|
||||
game.write_file('commands.log',
|
||||
@@ -120,32 +185,54 @@ local function run_custom_command(command)
|
||||
, true, 0)
|
||||
end
|
||||
|
||||
-- this is a set of constants you can use
|
||||
commands._add_command = commands.add_command --if you dont want to use the custom commands interface
|
||||
commands.expgaming = true --if you want to test if the custom commands are present
|
||||
commands.error = {} --if returned during a custom command, Command Complete message not printed
|
||||
--- Used to define commands
|
||||
-- @usage inputs = {'player','reason',true}
|
||||
-- commands.add_command('ban','bans a player',inputs,function() return end)
|
||||
-- @usage --see examples in file
|
||||
-- @tparam string name the name of the command
|
||||
-- @tparam[opt='No Description'] string description the description of the command
|
||||
-- @tparam[opt={'parameter',true}] table inputs a table of the inputs to be used, last index being true makes the last parameter open ended (longer than one word)
|
||||
-- @tparam function event the function to call on the event
|
||||
commands.add_command = function(name, description, inputs, event)
|
||||
if command_calls[name] then return end
|
||||
if not is_type(name,'string') then return end
|
||||
if not is_type(event,'function') then return end
|
||||
-- @tparam[opt=an infite string] table inputs a table of the inputs to be used, last index being true makes the last parameter open ended (longer than one word)
|
||||
-- @tparam function callback the function to call on the event
|
||||
commands.add_command = function(name, description, inputs, callback)
|
||||
if commands[name] then error('That command is already registered',2) end
|
||||
if not is_type(name,'string') then error('Command name has not been given') end
|
||||
if not is_type(callback,'function') or not is_type(inputs,'table') then
|
||||
if is_type(inputs,'function') then commands._add_command(name,description,inputs)
|
||||
else error('Invalid args given to add_command') end
|
||||
end
|
||||
verbose('Created Command: '..name)
|
||||
local description = is_type(description,'string') and description or 'No Description'
|
||||
local inputs = is_type(inputs,'table') and inputs or {'parameter',true}
|
||||
command_data[name] = {
|
||||
-- test for string and then test for locale string
|
||||
local description = is_type(description,'string') and description
|
||||
or is_type(description,'table') and is_type(description[1],'string') and string.find(description[1],'.+[.].+') and {description,''}
|
||||
or 'No Description'
|
||||
local inputs = is_type(inputs,'table') and inputs or {['param']={false,'string-inf'}}
|
||||
data[name] = {
|
||||
name=name,
|
||||
description=description,
|
||||
inputs=inputs
|
||||
inputs=inputs,
|
||||
callback=callback
|
||||
}
|
||||
command_calls[name] = event
|
||||
commands._add_command(name,command_inputs(command_data[name])..'- '..description,function(...)
|
||||
local help = is_type(description,'string') and commands.format_inputs(name)..'- '..description
|
||||
or is_type(description,'table') and is_type(description[1],'string') and string.find(description[1],'.+[.].+') and {description,commands.format_inputs(name)..'- '}
|
||||
or commands.format_inputs(name)
|
||||
data[name].help = help
|
||||
commands._add_command(name,help,function(...)
|
||||
local success, err = pcall(run_custom_command,...)
|
||||
if not success then error(err) end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
command example
|
||||
|
||||
locale file
|
||||
[foo]
|
||||
description=__1__ this is a command
|
||||
|
||||
commands.add_command('foo',{'foo.description'},{
|
||||
['player']={true,'player'}, -- a required arg that must be a valid player
|
||||
['number']={true,'number-range',0,10}, -- a required arg that must be a number 0<X<=10
|
||||
['reason']={false,'string-inf'} -- an optinal arg that is and infite lengh (useful for reasons)
|
||||
},function(event,args)
|
||||
args.player.print(args.number)
|
||||
if args.reasons then args.player.print(args.reason) end
|
||||
end)
|
||||
]]
|
||||
@@ -84,8 +84,10 @@ Ranking.groups = setmetatable({},{
|
||||
Ranking.meta = setmetatable({},{
|
||||
__metatable=false,
|
||||
__call=function(tbl)
|
||||
local count = 0
|
||||
rawset(tbl,'time_ranks',{})
|
||||
for name,rank in pairs(Ranking.ranks) do
|
||||
count=count+1
|
||||
if not rawget(tbl,'default') and rank.is_default then rawset(tbl,'default',rank.name) end
|
||||
if not rawget(tbl,'root') and rank.is_root then rawset(tbl,'root',rank.name) end
|
||||
if rank.time then
|
||||
@@ -94,6 +96,7 @@ Ranking.meta = setmetatable({},{
|
||||
if not rawget(tbl,'time_lowest') or rank.time < tbl.time_lowest then rawset(tbl,'time_lowest',rank.time) end
|
||||
end
|
||||
end
|
||||
rawset(tbl,'rank_count',count)
|
||||
if not rawget(tbl,'default') then error('No default rank') end
|
||||
if not rawget(tbl,'root') then error('No root rank') end
|
||||
end,
|
||||
@@ -444,6 +447,7 @@ Ranking.on_init=function(self)
|
||||
end
|
||||
end
|
||||
-- asigning of powers
|
||||
-- @todo need a better system for non liner rank trees
|
||||
verbose('Assigning Rank Powers')
|
||||
local power = 1
|
||||
local function set_powers(rank)
|
||||
|
||||
@@ -193,7 +193,10 @@ end
|
||||
-- @tparam[opt] ?Server._thread|true use_thread run the command on a premade thread or let it make its own
|
||||
-- @tparam[opt] table env run the env to run the command in must have _env key as true to be
|
||||
-- @param[opt] ... any args you want to pass to the function
|
||||
-- @return if no thread then it will return the value(s) returned by the callback
|
||||
-- @treturn[1] boolean if no thread then it will return a true for the success
|
||||
-- @return[1] if no thread then it will return the value(s) returned by the callback
|
||||
-- @treturn[2] boolean if no thread then it will return a false for the success
|
||||
-- @treturn[2] string if no thread then it will return a an err value
|
||||
function Server.interface(callback,use_thread,env,...)
|
||||
if use_thread then
|
||||
-- if use_thread is true then it makes a new thread
|
||||
@@ -217,15 +220,20 @@ function Server.interface(callback,use_thread,env,...)
|
||||
use_thread:open()
|
||||
Server.queue_thread(use_thread)
|
||||
else
|
||||
local callback = is_type(callback,'function') and callback or loadstring(callback)
|
||||
local _callback = callback
|
||||
if not is_type(callback,'function') then
|
||||
local rtn, err = loadstring(callback)
|
||||
if err then return false, err end
|
||||
_callback = rtn
|
||||
end
|
||||
if is_type(env,'table') and env._env == true then
|
||||
local sandbox, success, err = Manager.sandbox(callback,env,unpack(thread.data))
|
||||
if not success then error(err) end
|
||||
return err
|
||||
local sandbox, success, err = Manager.sandbox(_callback,env,...)
|
||||
if not success then error(err) return success,err
|
||||
else return success, unpack(err) end
|
||||
else
|
||||
local sandbox, success, err = Manager.sandbox(callback,{},env,unpack(thread.data))
|
||||
if not success then error(err) end
|
||||
return err
|
||||
local sandbox, success, err = Manager.sandbox(_callback,{},env,...)
|
||||
if not success then error(err) return success,err
|
||||
else return success, unpack(err) end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
--- Runs the given input from the script
|
||||
-- @command interface
|
||||
-- @param code The code that will be ran
|
||||
commands.add_command('interface', 'Runs the given input from the script', {'code',true}, function(event,args)
|
||||
commands.add_command('interface',{'Server.interface-description'}, {
|
||||
['code']={true,'string-inf'}
|
||||
}, function(event,args)
|
||||
local callback = args.code
|
||||
-- looks for spaces, if non the it will prefix the command with return
|
||||
if not string.find(callback,'%s') and not string.find(callback,'return') then callback = 'return '..callback end
|
||||
@@ -28,7 +30,7 @@ commands.add_command('interface', 'Runs the given input from the script', {'code
|
||||
-- runs the function
|
||||
local success, err = Server.interface(callback,false,env)
|
||||
-- if there is an error then it will remove the stacktrace and return the error
|
||||
if not success and is_type(err,'string') then local _end = string.find(err,'stack traceback') if _end then err = string.sub(err,0,_end-2) end end
|
||||
if not success and is_type(err,'string') then local _end = string.find(err,':1:') if _end then err = string.sub(err,_end+4) end end
|
||||
-- if there is a value returned that is not nill then it will return that value
|
||||
if err or err == false then player_return(err) end
|
||||
end)
|
||||
@@ -102,6 +102,7 @@ end
|
||||
-- @see EmitEmbededParamaters
|
||||
function Sync.emit_embeded(args)
|
||||
if not is_type(args,'table') then error('Args table not given to Sync.emit_embeded',2) end
|
||||
if not game then error('Game has not loaded',2) end
|
||||
local title = is_type(args.title,'string') and args.title or ''
|
||||
local color = is_type(args.color,'string') and args.color:find("0x") and args.color or '0x0'
|
||||
local description = is_type(args.description,'string') and args.description or ''
|
||||
|
||||
@@ -14,8 +14,11 @@
|
||||
"version": "3.4.0",
|
||||
"location": "url",
|
||||
"dependencies": {
|
||||
"ExpGamingLib": ">=4.0.0",
|
||||
"ExpGamingCore/Ranking": ">=4.0.0"
|
||||
"ExpGamingLib": "^4.0.0",
|
||||
"FactorioStdLib.Table": "^0.8.0",
|
||||
"FactorioStdLib.Color": "^0.8.0",
|
||||
"FactorioStdLib.Game": "^0.8.0",
|
||||
"ExpGamingCore/Ranking": "?^4.0.0"
|
||||
}
|
||||
},
|
||||
"Gui": {
|
||||
@@ -26,10 +29,10 @@
|
||||
"version": "3.4.0",
|
||||
"location": "url",
|
||||
"dependencies": {
|
||||
"FactorioModGui": ">=1.0.0",
|
||||
"ExpGamingLib": ">=4.0.0",
|
||||
"ExpGamingCore/Ranking": ">=4.0.0",
|
||||
"ExpGamingCore/Server": "?>=4.0.0"
|
||||
"FactorioModGui": "^1.0.0",
|
||||
"ExpGamingLib": "^4.0.0",
|
||||
"ExpGamingCore/Ranking": "^4.0.0",
|
||||
"ExpGamingCore/Server": "?^4.0.0"
|
||||
}
|
||||
},
|
||||
"Ranking": {
|
||||
@@ -40,10 +43,11 @@
|
||||
"version": "3.4.0",
|
||||
"location": "url",
|
||||
"dependencies": {
|
||||
"ExpGamingLib": ">=4.0.0",
|
||||
"FactorioStdLib.Color": ">=0.8.0",
|
||||
"FactorioStdLib.Table": ">=0.8.0",
|
||||
"ExpGamingCore.Server": "?>=4.0.0"
|
||||
"ExpGamingLib": "^4.0.0",
|
||||
"FactorioStdLib.Color": "^0.8.0",
|
||||
"FactorioStdLib.Table": "^0.8.0",
|
||||
"FactorioStdLib.Game": "^0.8.0",
|
||||
"ExpGamingCore.Server": "?^4.0.0"
|
||||
}
|
||||
},
|
||||
"Server": {
|
||||
@@ -54,10 +58,11 @@
|
||||
"version": "3.4.0",
|
||||
"location": "url",
|
||||
"dependencies": {
|
||||
"ExpGamingLib": ">=4.0.0",
|
||||
"FactorioStdLib.Table": ">=0.8.0",
|
||||
"ExpGamingCore.Ranking": "?>=4.0.0",
|
||||
"ExpGamingCore.Commands": "?>=4.0.0"
|
||||
"ExpGamingLib": "^4.0.0",
|
||||
"FactorioStdLib.Table": "^0.8.0",
|
||||
"FactorioStdLib.Game": "^0.8.0",
|
||||
"ExpGamingCore.Ranking": "?^4.0.0",
|
||||
"ExpGamingCore.Commands": "?^4.0.0"
|
||||
}
|
||||
},
|
||||
"Sync": {
|
||||
@@ -68,11 +73,11 @@
|
||||
"version": "3.4.0",
|
||||
"location": "url",
|
||||
"dependencies": {
|
||||
"ExpGamingLib": ">=4.0.0",
|
||||
"FactorioStdLib.Color": ">=0.8.0",
|
||||
"FactorioStdLib.Table": ">=0.8.0",
|
||||
"ExpGamingCore.Ranking": "?>=4.0.0",
|
||||
"ExpGamingCore.Gui": "?>=4.0.0"
|
||||
"ExpGamingLib": "^4.0.0",
|
||||
"FactorioStdLib.Color": "^0.8.0",
|
||||
"FactorioStdLib.Table": "^0.8.0",
|
||||
"ExpGamingCore.Ranking": "?^4.0.0",
|
||||
"ExpGamingCore.Gui": "?^4.0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user