From e37e846ea103fd7994c6dc0fc5c201c47d493f47 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Thu, 28 May 2020 21:27:18 +0100 Subject: [PATCH 01/11] Updated Player Data Core --- config/expcore/roles.lua | 5 ++-- expcore/player_data.lua | 49 ++++++++++++++++++++++++++++++++++++---- locale/en/expcore.cfg | 5 +++- 3 files changed, 52 insertions(+), 7 deletions(-) diff --git a/config/expcore/roles.lua b/config/expcore/roles.lua index 4d9f9dad..383569a4 100644 --- a/config/expcore/roles.lua +++ b/config/expcore/roles.lua @@ -220,8 +220,9 @@ local default = Roles.new_role('Guest','') 'command/report', 'command/ratio', 'command/server-ups', - 'command/data-preference', - 'command/set-data-preference', + 'command/save-data', + 'command/preference', + 'command/set-preference', 'gui/player-list', 'gui/rocket-info', 'gui/science-info', diff --git a/expcore/player_data.lua b/expcore/player_data.lua index 057ae404..d6157f5c 100644 --- a/expcore/player_data.lua +++ b/expcore/player_data.lua @@ -42,10 +42,18 @@ end) ]] local Event = require 'utils.event' --- @dep utils.event +local Async = require 'expcore.async' --- @dep expcore.async local Datastore = require 'expcore.datastore' --- @dep expcore.datastore local Commands = require 'expcore.commands' --- @dep expcore.commands require 'config.expcore.command_general_parse' --- @dep config.expcore.command_general_parse +--- Stores all the players whos data failed to load +local FailedLoad = {} +global.failed_player_data = FailedLoad +Event.on_load(function() + FailedLoad = global.failed_player_data +end) + --- Common player data that acts as the root store for player data local PlayerData = Datastore.connect('PlayerData', true) -- saveToDisk PlayerData:set_serializer(Datastore.name_serializer) -- use player name @@ -58,7 +66,7 @@ DataSavingPreference:set_default('All') --- Sets your data saving preference -- @command set-data-preference -Commands.new_command('set-data-preference', 'Allows you to set your data saving preference') +Commands.new_command('set-preference', 'Allows you to set your data saving preference') :add_param('option', false, 'string-options', PreferenceEnum) :register(function(player, option) DataSavingPreference:set(player, option) @@ -67,11 +75,37 @@ end) --- Gets your data saving preference -- @command data-preference -Commands.new_command('data-preference', 'Shows you what your current data saving preference is') +Commands.new_command('preference', 'Shows you what your current data saving preference is') :register(function(player) return {'expcore-data.get-preference', DataSavingPreference:get(player)} end) +--- Gets your data and writes it to a file +Commands.new_command('save-data', 'Writes all your player data to a file on your computer') +:register(function(player) + player.print{'expcore-data.get-data'} + game.write_file('expgaming_player_data.json', game.table_to_json(PlayerData:get(player, {})), false, player.index) +end) + +--- Async function called after 10 seconds with no player data loaded +local check_data_loaded = Async.register(function(player) + local player_data = PlayerData:get(player) + if not player_data then + FailedLoad[player.name] = true + player.print{'expcore-data.data-failed'} + Datastore.ingest('request', 'PlayerData', player.name, '{"failed_load":true}') + end +end) + +--- When player data loads tell the player if the load had failed previously +PlayerData:on_load(function(player_name, player_data) + if not player_data or player_data.failed_load then return end + if FailedLoad[player_name] then + FailedLoad[player_name] = nil + game.players[player_name].print{'expcore-data.data-restore'} + end +end) + --- Remove data that the player doesnt want to have stored PlayerData:on_save(function(player_name, player_data) local dataPreference = DataSavingPreference:get(player_name) @@ -92,12 +126,19 @@ end) --- Load player data when they join Event.add(defines.events.on_player_joined_game, function(event) - PlayerData:request(game.players[event.player_index]) + local player = game.players[event.player_index] + PlayerData:request(player) + Async.wait(600, check_data_loaded, player) end) --- Unload player data when they leave Event.add(defines.events.on_player_left_game, function(event) - PlayerData:unload(game.players[event.player_index]) + local player = game.players[event.player_index] + local player_data = PlayerData:get(player) + if player_data.failed_load then + FailedLoad[player.name] = nil + PlayerData:raw_set(player) + else PlayerData:unload(player) end end) ----- Module Return ----- diff --git a/locale/en/expcore.cfg b/locale/en/expcore.cfg index 5fd4fefe..7d50cd29 100644 --- a/locale/en/expcore.cfg +++ b/locale/en/expcore.cfg @@ -39,4 +39,7 @@ left-button-tooltip=Hide all open windows. [expcore-data] set-preference=You data saving preference has been set to __1__. Existing data will not be effected until you rejoin. -get-preference=You data saving preference is __1__. Use /set-data-preference to change this. \ No newline at end of file +get-preference=You data saving preference is __1__. Use /set-preference to change this. Use /save-data to get a local copy of your data. +get-data=Your player data has been writen to file, location: factorio/script_output/expgaming_player_data.json +data-failed=Your player data has failed to load. Any changes to your data will not be saved. +data-restore=Your player data has been restored and changes will now save when you leave. \ No newline at end of file From c26b54f2772739ebda2c54491ef84ab24e16dc7e Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Thu, 28 May 2020 22:08:21 +0100 Subject: [PATCH 02/11] Added player colours to player data --- config/_file_loader.lua | 2 +- modules/addons/player-colours.lua | 50 ++++++++++++++++++++++++ modules/addons/random-player-colours.lua | 29 -------------- 3 files changed, 51 insertions(+), 30 deletions(-) create mode 100644 modules/addons/player-colours.lua delete mode 100644 modules/addons/random-player-colours.lua diff --git a/config/_file_loader.lua b/config/_file_loader.lua index ce035ac0..c2a79ccf 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -42,7 +42,7 @@ return { 'modules.addons.compilatron', 'modules.addons.scorched-earth', 'modules.addons.pollution-grading', - 'modules.addons.random-player-colours', + 'modules.addons.player-colours', 'modules.addons.discord-alerts', 'modules.addons.chat-reply', 'modules.addons.tree-decon', diff --git a/modules/addons/player-colours.lua b/modules/addons/player-colours.lua new file mode 100644 index 00000000..74732d67 --- /dev/null +++ b/modules/addons/player-colours.lua @@ -0,0 +1,50 @@ +--- Gives players random colours when they join, also applies preset colours to those who have them +-- @addon Player-Colours + +local Event = require 'utils.event' --- @dep utils.event +local Colours = require 'utils.color_presets' --- @dep utils.color_presets +local config = require 'config.preset_player_colours' --- @dep config.preset_player_colours + +--- Stores the colour that the player wants +local PlayerData = require 'expcore.player_data' --- @dep expcore.player_data +local PlayerColours = PlayerData.Settings:combine('Colour') + +--- Used to compact player colours to take less space +local floor = math.floor +local function compact(colour) + return { + floor(colour.r * 255), + floor(colour.g * 255), + floor(colour.b * 255) + } +end + +--- When your data loads apply the players colour, or a random on if none is saved +PlayerColours:on_load(function(player_name, player_colour) + if not player_colour then + local preset = config.players[player_name] + if preset then + player_colour = {preset, preset} + else + local colour_name = 'white' + while config.disallow[colour_name] do + colour_name = table.get_random_dictionary_entry(Colours, true) + end + player_colour = {Colours[colour_name], Colours[colour_name]} + end + end + + local player = game.players[player_name] + player.color = player_colour[1] + player.chat_color = player_colour[2] +end) + +--- Save the players color when they use the color command +Event.add(defines.events.on_console_command, function(event) + if event.command ~= 'color' then return end + if event.parameters == '' then return end + if not event.player_index then return end + local player = game.players[event.player_index] + if not player or not player.valid then return end + PlayerColours:set(player, {compact(player.color), compact(player.chat_color)}) +end) \ No newline at end of file diff --git a/modules/addons/random-player-colours.lua b/modules/addons/random-player-colours.lua deleted file mode 100644 index 17b95ddb..00000000 --- a/modules/addons/random-player-colours.lua +++ /dev/null @@ -1,29 +0,0 @@ ---- Gives players random colours when they join, also applies preset colours to those who have them --- @addon Player-Colours - -local Colours = require 'utils.color_presets' --- @dep utils.color_presets -local Game = require 'utils.game' --- @dep utils.game -local Event = require 'utils.event' --- @dep utils.event -local config = require 'config.preset_player_colours' --- @dep config.preset_player_colours -local Global = require 'utils.global' --- @dep utils.global -require 'overrides.table' - -Global.register(config, function(tbl) - config = tbl -end) - -Event.add(defines.events.on_player_created, function(event) - local player = Game.get_player_by_index(event.player_index) - local color = 'white' - if config.players[player.name] then - color = config.players[player.name] - else - while config.disallow[color] do - color = table.get_random_dictionary_entry(Colours, true) - end - color = Colours[color] - end - color = {r=color.r/255, g=color.g/255, b=color.b/255, a=0.5} - player.color = color - player.chat_color = color -end) \ No newline at end of file From c75c123b35e11b9eeb5384998288aef1a8c5d604 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Thu, 28 May 2020 22:19:18 +0100 Subject: [PATCH 03/11] Added Custom Join Message --- config/_file_loader.lua | 8 ++++-- locale/en/addons.cfg | 5 +--- locale/en/commands.cfg | 6 +++- modules/addons/greetings.lua | 26 ----------------- modules/data/greetings.lua | 32 +++++++++++++++++++++ modules/{addons => data}/player-colours.lua | 0 6 files changed, 43 insertions(+), 34 deletions(-) delete mode 100644 modules/addons/greetings.lua create mode 100644 modules/data/greetings.lua rename modules/{addons => data}/player-colours.lua (100%) diff --git a/config/_file_loader.lua b/config/_file_loader.lua index c2a79ccf..8e9de264 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -32,8 +32,6 @@ return { 'modules.commands.quickbar', --- Addons - 'modules.addons.station-auto-name', - 'modules.addons.greetings', 'modules.addons.chat-popups', 'modules.addons.damage-popups', 'modules.addons.death-logger', @@ -42,11 +40,15 @@ return { 'modules.addons.compilatron', 'modules.addons.scorched-earth', 'modules.addons.pollution-grading', - 'modules.addons.player-colours', + 'modules.addons.station-auto-name', 'modules.addons.discord-alerts', 'modules.addons.chat-reply', 'modules.addons.tree-decon', + --- Data + 'modules.data.player-colours', + 'modules.data.greetings', + --- GUI 'modules.gui.readme', 'modules.gui.rocket-info', diff --git a/locale/en/addons.cfg b/locale/en/addons.cfg index 4cb4c837..ed0d9123 100644 --- a/locale/en/addons.cfg +++ b/locale/en/addons.cfg @@ -77,7 +77,4 @@ get-mead-1= Filling the drinking horn get-mead-2= Skål! get-beer-1= 🍺 Pouring A Glass 🍺 get-beer-2= 🍻 Chears Mate 🍻 -verify=Please return to our discord and type r!verify __1__ - -[greetings] -greet=[color=0,1,0] Welcome to explosive gaming community server! If you like the server join our discord: __1__ [/color] \ No newline at end of file +verify=Please return to our discord and type r!verify __1__ \ No newline at end of file diff --git a/locale/en/commands.cfg b/locale/en/commands.cfg index 081b8f36..f4555dec 100644 --- a/locale/en/commands.cfg +++ b/locale/en/commands.cfg @@ -75,4 +75,8 @@ return-set=Your return point has been set to x: __1__ y: __2__ home-get=Your home point is at x: __1__ y: __2__ [expcom-server-ups] -no-ext=No external source was found, cannot display server ups. \ No newline at end of file +no-ext=No external source was found, cannot display server ups. + +[expcom-join-message] +greet=[color=0,1,0] Welcome to explosive gaming community server! If you like the server join our discord: __1__ [/color] +message-set=Your join message has been updated. \ No newline at end of file diff --git a/modules/addons/greetings.lua b/modules/addons/greetings.lua deleted file mode 100644 index 093cf1b5..00000000 --- a/modules/addons/greetings.lua +++ /dev/null @@ -1,26 +0,0 @@ ---- Greets players on join --- @addon greetings - -local Event = require 'utils.event' --- @dep utils.event -local Game = require 'utils.game' --- @dep utils.event -local config = require 'config.join_messages' --- @dep config.join_messages -local Global = require 'utils.global' --- @dep utils.global -require 'overrides.table' - -Global.register(config, function(tbl) - config = tbl -end) - -local greet = -function(event) - local player = Game.get_player_by_index(event.player_index) - local custom_message = config[player.name] - if custom_message then - game.print(custom_message, player.color) - else - player.print{'greetings.greet', {'links.discord'}} - end - -end - -Event.add(defines.events.on_player_joined_game, greet) \ No newline at end of file diff --git a/modules/data/greetings.lua b/modules/data/greetings.lua new file mode 100644 index 00000000..45d487f7 --- /dev/null +++ b/modules/data/greetings.lua @@ -0,0 +1,32 @@ +--- Greets players on join +-- @addon greetings + +local Commands = require 'expcore.commands' ---@dep expcore.commands +local config = require 'config.join_messages' --- @dep config.join_messages + +--- Stores the join message that the player have +local PlayerData = require 'expcore.player_data' --- @dep expcore.player_data +local CustomMessages = PlayerData.Settings:combine('JoinMessage') + +--- When a players data loads show their message +CustomMessages:on_load(function(player_name, player_message) + local player = game.players[player_name] + local custom_message = player_message or config[player_name] + if custom_message then + game.print(custom_message, player.color) + else + player.print{'expcom-join-message.greet', {'links.discord'}} + end +end) + +--- Set your custom join message +-- @command join-message +-- @tparam string message The custom join message that will be used +Commands.new_command('join-message', 'Sets your custom join message') +:add_param('message', false) +:enable_auto_concat() +:register(function(player, message) + if not player then return end + CustomMessages:set(player, message) + return {'expcom-join-message.message-set'} +end) \ No newline at end of file diff --git a/modules/addons/player-colours.lua b/modules/data/player-colours.lua similarity index 100% rename from modules/addons/player-colours.lua rename to modules/data/player-colours.lua From d65a1fe0fefec17dd372860d192ac3300fbe72d8 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Thu, 28 May 2020 22:31:24 +0100 Subject: [PATCH 04/11] Added Quickbar filters --- config/_file_loader.lua | 2 +- config/expcore/roles.lua | 8 +++---- locale/en/commands.cfg | 6 +---- locale/en/data.cfg | 6 +++++ modules/commands/quickbar.lua | 40 ------------------------------- modules/data/greetings.lua | 4 ++-- modules/data/quickbar.lua | 45 +++++++++++++++++++++++++++++++++++ 7 files changed, 59 insertions(+), 52 deletions(-) create mode 100644 locale/en/data.cfg delete mode 100644 modules/commands/quickbar.lua create mode 100644 modules/data/quickbar.lua diff --git a/config/_file_loader.lua b/config/_file_loader.lua index 8e9de264..65d8f093 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -29,7 +29,6 @@ return { 'modules.commands.find', 'modules.commands.bonus', 'modules.commands.home', - 'modules.commands.quickbar', --- Addons 'modules.addons.chat-popups', @@ -48,6 +47,7 @@ return { --- Data 'modules.data.player-colours', 'modules.data.greetings', + 'modules.data.quickbar', --- GUI 'modules.gui.readme', diff --git a/config/expcore/roles.lua b/config/expcore/roles.lua index 383569a4..3b4b225d 100644 --- a/config/expcore/roles.lua +++ b/config/expcore/roles.lua @@ -140,9 +140,7 @@ Roles.new_role('Sponsor','Spon') 'command/home-set', 'command/home-get', 'command/return', - 'fast-tree-decon', - 'command/load-quickbar', - 'command/save-quickbar' + 'fast-tree-decon' } Roles.new_role('Supporter','Sup') @@ -152,7 +150,9 @@ Roles.new_role('Supporter','Sup') :set_parent('Veteran') :allow{ 'command/jail', - 'command/unjail' + 'command/unjail', + 'command/join-message', + 'command/save-quickbar' } Roles.new_role('Partner','Part') diff --git a/locale/en/commands.cfg b/locale/en/commands.cfg index f4555dec..081b8f36 100644 --- a/locale/en/commands.cfg +++ b/locale/en/commands.cfg @@ -75,8 +75,4 @@ return-set=Your return point has been set to x: __1__ y: __2__ home-get=Your home point is at x: __1__ y: __2__ [expcom-server-ups] -no-ext=No external source was found, cannot display server ups. - -[expcom-join-message] -greet=[color=0,1,0] Welcome to explosive gaming community server! If you like the server join our discord: __1__ [/color] -message-set=Your join message has been updated. \ No newline at end of file +no-ext=No external source was found, cannot display server ups. \ No newline at end of file diff --git a/locale/en/data.cfg b/locale/en/data.cfg new file mode 100644 index 00000000..6816c16b --- /dev/null +++ b/locale/en/data.cfg @@ -0,0 +1,6 @@ +[join-message] +greet=[color=0,1,0] Welcome to explosive gaming community server! If you like the server join our discord: __1__ [/color] +message-set=Your join message has been updated. + +[quickbar] +saved=Your quickbar filters have been saved. \ No newline at end of file diff --git a/modules/commands/quickbar.lua b/modules/commands/quickbar.lua deleted file mode 100644 index c297ddfe..00000000 --- a/modules/commands/quickbar.lua +++ /dev/null @@ -1,40 +0,0 @@ ---[[-- Commands Module - Quickbar - - Adds a command that allows players to load Quickbar presets - @commands Quickbar -]] - -local Commands = require 'expcore.commands' --- @dep expcore.commands -local config = require 'config.preset_player_quickbar' --- @dep config.preset_player_quickbar - ---- Loads your quickbar preset --- @command load-quickbar -Commands.new_command('load-quickbar', 'Loads your preset Quickbar items') -:add_alias('load-toolbar') -:register(function(player) - if config[player.name] then - local custom_quickbar = config[player.name] - for i, item_name in pairs(custom_quickbar) do - if item_name ~= nil and item_name ~= '' then - player.set_quick_bar_slot(i, item_name) - end - end - else - Commands.error('Quickbar preset not found') - end -end) - ---- Saves your quickbar preset to the script-output folder --- @command save-quickbar -Commands.new_command('save-quickbar', 'Saves your Quickbar preset items to file') -:add_alias('save-toolbar') -:register(function(player) - local quickbar_names = {} - for i=1, 100 do - local slot = player.get_quick_bar_slot(i) - if slot ~= nil then - quickbar_names[i] = slot.name - end - end - game.write_file("quickbar_preset.txt", player.name .. " = " .. serpent.line(quickbar_names) .. "\n", true) - Commands.print("Quickbar saved") -end) diff --git a/modules/data/greetings.lua b/modules/data/greetings.lua index 45d487f7..6816d0cc 100644 --- a/modules/data/greetings.lua +++ b/modules/data/greetings.lua @@ -15,7 +15,7 @@ CustomMessages:on_load(function(player_name, player_message) if custom_message then game.print(custom_message, player.color) else - player.print{'expcom-join-message.greet', {'links.discord'}} + player.print{'join-message.greet', {'links.discord'}} end end) @@ -28,5 +28,5 @@ Commands.new_command('join-message', 'Sets your custom join message') :register(function(player, message) if not player then return end CustomMessages:set(player, message) - return {'expcom-join-message.message-set'} + return {'join-message.message-set'} end) \ No newline at end of file diff --git a/modules/data/quickbar.lua b/modules/data/quickbar.lua new file mode 100644 index 00000000..5c53f183 --- /dev/null +++ b/modules/data/quickbar.lua @@ -0,0 +1,45 @@ +--[[-- Commands Module - Quickbar + - Adds a command that allows players to load Quickbar presets + @commands Quickbar +]] + +local Commands = require 'expcore.commands' --- @dep expcore.commands +local config = require 'config.preset_player_quickbar' --- @dep config.preset_player_quickbar + +--- Stores the quickbar filters for a player +local PlayerData = require 'expcore.player_data' --- @dep expcore.player_data +local PlayerFilters = PlayerData.Settings:combine('QuickbarFilters') + +--- Loads your quickbar preset +PlayerFilters:on_load(function(player_name, filters) + if not filters then filters = config[player_name] end + if not filters then return end + local player = game.players[player_name] + for i, item_name in pairs(filters) do + if item_name ~= nil and item_name ~= '' then + player.set_quick_bar_slot(i, item_name) + end + end +end) + +--- Saves your quickbar preset to the script-output folder +-- @command save-quickbar +Commands.new_command('save-quickbar', 'Saves your Quickbar preset items to file') +:add_alias('save-toolbar') +:register(function(player) + local filters = {} + for i = 1, 100 do + local slot = player.get_quick_bar_slot(i) + if slot ~= nil then + filters[i] = slot.name + end + end + + if next(filters) then + PlayerFilters:set(player, filters) + else + PlayerFilters:remove(player) + end + + return {'quickbar.saved'} +end) \ No newline at end of file From 6a5d5f02d9a35c648ab2be59688faadea534f6ad Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Thu, 28 May 2020 22:43:58 +0100 Subject: [PATCH 05/11] Added player tags --- modules/{commands => data}/tag.lua | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) rename modules/{commands => data}/tag.lua (72%) diff --git a/modules/commands/tag.lua b/modules/data/tag.lua similarity index 72% rename from modules/commands/tag.lua rename to modules/data/tag.lua index 7b256f9c..693d5346 100644 --- a/modules/commands/tag.lua +++ b/modules/data/tag.lua @@ -8,6 +8,20 @@ local Roles = require 'expcore.roles' --- @dep expcore.roles require 'config.expcore.command_general_parse' require 'config.expcore.command_role_parse' +--- Stores the tag for a player +local PlayerData = require 'expcore.player_data' --- @dep expcore.player_data +local PlayerTags = PlayerData.Settings:combine('Tag') + +--- When your tag is updated then apply the changes +PlayerTags:on_update(function(player_name, player_tag) + local player = game.players[player_name] + if player_tag == nil or player_tag == '' then + player_tag.tag = '' + else + player.tag = '- '..player_tag + end +end) + --- Sets your player tag. -- @command tag -- @tparam string tag the tag that will be after the name, there is a max length @@ -15,7 +29,7 @@ Commands.new_command('tag', 'Sets your player tag.') :add_param('tag', false, 'string-max-length', 20) :enable_auto_concat() :register(function(player, tag) - player.tag = '- '..tag + PlayerTags:set(player, tag) end) --- Clears your tag. Or another player if you are admin. @@ -29,10 +43,10 @@ end} :register(function(player, action_player) if action_player.index == player.index then -- no player given so removes your tag - action_player.tag = '' + PlayerTags:remove(action_player) elseif Roles.player_allowed(player, 'command/clear-tag/always') then -- player given and user is admin so clears that player's tag - action_player.tag = '' + PlayerTags:remove(action_player) else -- user is not admin and tried to clear another users tag return Commands.error{'expcore-commands.unauthorized'} From bfcb22918590d1fafd7ef9408119b532a77e0491 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Thu, 28 May 2020 22:52:15 +0100 Subject: [PATCH 06/11] Added player bonus --- modules/{commands => data}/bonus.lua | 43 ++++++++++++---------------- modules/data/greetings.lua | 5 ++-- 2 files changed, 22 insertions(+), 26 deletions(-) rename modules/{commands => data}/bonus.lua (62%) diff --git a/modules/commands/bonus.lua b/modules/data/bonus.lua similarity index 62% rename from modules/commands/bonus.lua rename to modules/data/bonus.lua index 28327eaa..7bf686c5 100644 --- a/modules/commands/bonus.lua +++ b/modules/data/bonus.lua @@ -11,12 +11,11 @@ local Store = require 'expcore.store' --- @dep expcore.store local config = require 'config.bonuses' --- @dep config.bonuses require 'config.expcore.command_general_parse' --- Store bonus percentages keyed by player name -local bonus_store = Store.register(function(player) - return player.name -end) +--- Stores the bonus for the player +local PlayerData = require 'expcore.player_data' --- @dep expcore.player_data +local PlayerBonus = PlayerData.Settings:combine('Bonus') --- Apply a bonus amount to a player +--- Apply a bonus amount to a player local function apply_bonus(player, amount) if not amount then return end for bonus, min_max in pairs(config) do @@ -25,6 +24,11 @@ local function apply_bonus(player, amount) end end +--- When store is updated apply new bonus to the player +PlayerBonus.on_update(function(player_name, player_bonus) + apply_bonus(game.player[player_name], player_bonus or 0) +end) + --- Changes the amount of bonus you receive -- @command bonus -- @tparam number amount range 0-50 the percent increase for your bonus @@ -32,41 +36,32 @@ Commands.new_command('bonus', 'Changes the amount of bonus you receive') :add_param('amount', 'integer-range', 0,50) :register(function(player, amount) local percent = amount/100 - Store.set(bonus_store, player, percent) + PlayerBonus:set(player, percent) Commands.print{'expcom-bonus.set', amount} Commands.print({'expcom-bonus.wip'}, 'orange') end) --- When store is updated apply new bonus to the player -Store.watch(bonus_store, function(value, category) - local player = Game.get_player_from_any(category) - apply_bonus(player, value) -end) - --- When a player respawns re-apply bonus +--- When a player respawns re-apply bonus Event.add(defines.events.on_player_respawned, function(event) - local player = Game.get_player_by_index(event.player_index) - local value = Store.get(bonus_store, player) - apply_bonus(player, value) + local player = game.players[event.player_index] + apply_bonus(player, PlayerBonus:get(player)) end) --- When a player dies allow them to have instant respawn +--- When a player dies allow them to have instant respawn Event.add(defines.events.on_player_died, function(event) - local player = Game.get_player_by_index(event.player_index) + local player = game.players[event.player_index] if Roles.player_has_flag(player, 'instance-respawn') then player.ticks_to_respawn = 120 end end) --- Remove bonus if a player no longer has access to the command +--- Remove bonus if a player no longer has access to the command local function role_update(event) - local player = Game.get_player_by_index(event.player_index) + local player = game.players[event.player_index] if not Roles.player_allowed(player, 'command/bonus') then - Store.clear(bonus_store, player) + PlayerBonus:remove(player) end end Event.add(Roles.events.on_role_assigned, role_update) -Event.add(Roles.events.on_role_unassigned, role_update) - -return bonus_store \ No newline at end of file +Event.add(Roles.events.on_role_unassigned, role_update) \ No newline at end of file diff --git a/modules/data/greetings.lua b/modules/data/greetings.lua index 6816d0cc..04a736cd 100644 --- a/modules/data/greetings.lua +++ b/modules/data/greetings.lua @@ -1,8 +1,9 @@ --- Greets players on join -- @addon greetings -local Commands = require 'expcore.commands' ---@dep expcore.commands local config = require 'config.join_messages' --- @dep config.join_messages +local Commands = require 'expcore.commands' ---@dep expcore.commands +require 'config.expcore.command_general_parse' --- Stores the join message that the player have local PlayerData = require 'expcore.player_data' --- @dep expcore.player_data @@ -23,7 +24,7 @@ end) -- @command join-message -- @tparam string message The custom join message that will be used Commands.new_command('join-message', 'Sets your custom join message') -:add_param('message', false) +:add_param('message', false, 'string-max-length', 255) :enable_auto_concat() :register(function(player, message) if not player then return end From 0836375e0251a6ae1f249b7b822a15fa2a2f8dbe Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Thu, 28 May 2020 23:08:08 +0100 Subject: [PATCH 07/11] Added Alt View --- docs/config.ld | 1 + modules/data/alt-view.lua | 21 +++++++++++++++++++++ modules/data/bonus.lua | 6 ++---- modules/data/greetings.lua | 2 +- modules/data/player-colours.lua | 2 +- modules/data/quickbar.lua | 2 +- modules/data/tag.lua | 2 +- 7 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 modules/data/alt-view.lua diff --git a/docs/config.ld b/docs/config.ld index 30e23b4b..68c0c7a5 100644 --- a/docs/config.ld +++ b/docs/config.ld @@ -19,6 +19,7 @@ new_type("core", "Core", true) new_type("control", "Control", true) new_type("addon", "Addons", true) new_type("gui", "Guis", true) +new_type("data", "Data", true) new_type("commands", "Commands", true) new_type("config", "Configs", true, "Settings") diff --git a/modules/data/alt-view.lua b/modules/data/alt-view.lua new file mode 100644 index 00000000..83aca25a --- /dev/null +++ b/modules/data/alt-view.lua @@ -0,0 +1,21 @@ +--- Stores if you use alt mode or not and auto applies it +-- @data Alt-View + +local Event = require 'utils.event' ---@dep utils.event + +--- Stores the join message that the player have +local PlayerData = require 'expcore.player_data' --- @dep expcore.player_data +local UsesAlt = PlayerData.Settings:combine('UsesAlt') +UsesAlt:set_default(false) + +--- When your data loads apply alt view if you have it enabled +UsesAlt:on_load(function(player_name, uses_alt) + local player = game.players[player_name] + player.game_view_settings.show_entity_info = uses_alt or false +end) + +--- When alt view is toggled update this +Event.add(defines.events.on_player_toggled_alt_mode, function(event) + local player = game.players[event.player_index] + UsesAlt:set(player, player.game_view_settings.show_entity_info) +end) \ No newline at end of file diff --git a/modules/data/bonus.lua b/modules/data/bonus.lua index 7bf686c5..6cf1752f 100644 --- a/modules/data/bonus.lua +++ b/modules/data/bonus.lua @@ -1,14 +1,12 @@ --[[-- Commands Module - Bonus - Adds a command that allows players to have increased stats - @commands Bonus + @data Bonus ]] -local Commands = require 'expcore.commands' --- @dep expcore.commands local Roles = require 'expcore.roles' --- @dep expcore.roles local Event = require 'utils.event' --- @dep utils.event -local Game = require 'utils.game' --- @dep utils.game -local Store = require 'expcore.store' --- @dep expcore.store local config = require 'config.bonuses' --- @dep config.bonuses +local Commands = require 'expcore.commands' --- @dep expcore.commands require 'config.expcore.command_general_parse' --- Stores the bonus for the player diff --git a/modules/data/greetings.lua b/modules/data/greetings.lua index 04a736cd..84def7e3 100644 --- a/modules/data/greetings.lua +++ b/modules/data/greetings.lua @@ -1,5 +1,5 @@ --- Greets players on join --- @addon greetings +-- @data Greetings local config = require 'config.join_messages' --- @dep config.join_messages local Commands = require 'expcore.commands' ---@dep expcore.commands diff --git a/modules/data/player-colours.lua b/modules/data/player-colours.lua index 74732d67..bed8012f 100644 --- a/modules/data/player-colours.lua +++ b/modules/data/player-colours.lua @@ -1,5 +1,5 @@ --- Gives players random colours when they join, also applies preset colours to those who have them --- @addon Player-Colours +-- @data Player-Colours local Event = require 'utils.event' --- @dep utils.event local Colours = require 'utils.color_presets' --- @dep utils.color_presets diff --git a/modules/data/quickbar.lua b/modules/data/quickbar.lua index 5c53f183..d2352a7f 100644 --- a/modules/data/quickbar.lua +++ b/modules/data/quickbar.lua @@ -1,6 +1,6 @@ --[[-- Commands Module - Quickbar - Adds a command that allows players to load Quickbar presets - @commands Quickbar + @data Quickbar ]] local Commands = require 'expcore.commands' --- @dep expcore.commands diff --git a/modules/data/tag.lua b/modules/data/tag.lua index 693d5346..644fc0f3 100644 --- a/modules/data/tag.lua +++ b/modules/data/tag.lua @@ -1,6 +1,6 @@ --[[-- Commands Module - Tag - Adds a command that allows players to have a custom tag after their name - @commands Tag + @data Tag ]] local Commands = require 'expcore.commands' --- @dep expcore.commands From 4286e25803f84d1aa8c417aba877d80d9836df52 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Fri, 29 May 2020 22:57:06 +0100 Subject: [PATCH 08/11] Fixed some bugs --- config/_file_loader.lua | 5 +++-- config/expcore/roles.lua | 6 +++--- expcore/datastore.lua | 20 ++++++++++---------- expcore/player_data.lua | 17 ++++------------- modules/data/bonus.lua | 4 ++-- modules/data/tag.lua | 2 +- 6 files changed, 23 insertions(+), 31 deletions(-) diff --git a/config/_file_loader.lua b/config/_file_loader.lua index 65d8f093..28d4ebde 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -12,7 +12,6 @@ return { 'modules.commands.me', 'modules.commands.kill', 'modules.commands.admin-chat', - 'modules.commands.tag', 'modules.commands.teleport', 'modules.commands.cheat-mode', 'modules.commands.ratio', @@ -27,7 +26,6 @@ return { 'modules.commands.spawn', 'modules.commands.warnings', 'modules.commands.find', - 'modules.commands.bonus', 'modules.commands.home', --- Addons @@ -48,6 +46,9 @@ return { 'modules.data.player-colours', 'modules.data.greetings', 'modules.data.quickbar', + 'modules.data.alt-view', + 'modules.data.tag', + 'modules.data.bonus', --- GUI 'modules.gui.readme', diff --git a/config/expcore/roles.lua b/config/expcore/roles.lua index 3b4b225d..c1904ada 100644 --- a/config/expcore/roles.lua +++ b/config/expcore/roles.lua @@ -151,8 +151,7 @@ Roles.new_role('Supporter','Sup') :allow{ 'command/jail', 'command/unjail', - 'command/join-message', - 'command/save-quickbar' + 'command/join-message' } Roles.new_role('Partner','Part') @@ -187,7 +186,8 @@ Roles.new_role('Member','Mem') 'gui/task-list/add', 'gui/task-list/edit', 'gui/warp-list/add', - 'gui/warp-list/edit' + 'gui/warp-list/edit', + 'command/save-quickbar' } Roles.new_role('Regular','Reg') diff --git a/expcore/datastore.lua b/expcore/datastore.lua index be6848e4..f13a4c50 100644 --- a/expcore/datastore.lua +++ b/expcore/datastore.lua @@ -153,6 +153,7 @@ local Datastores = {} local Datastore = {} local Data = {} local copy = table.deep_copy +local trace = debug.traceback --- Save datastores in the global table global.datastores = Data @@ -250,7 +251,6 @@ function DatastoreManager.ingest(action, datastoreName, key, valueJson) elseif action == 'propagate' or action == 'request' then local success, value = pcall(game.json_to_table, valueJson) if not success or value == nil then value = tonumber(valueJson) or valueJson end - datastore:raw_set(key) -- clear any existing data value = datastore:raise_event('on_load', key, value) datastore:set(key, value) @@ -360,7 +360,7 @@ function Datastore:raw_set(key, value) end end -local function serialize_error(err) error('An error ocurred in a datastore serializer: '..err) end +local function serialize_error(err) error('An error ocurred in a datastore serializer: '..trace(err)) end --[[-- Internal, Return the serialized key @tparam any rawKey The key that needs to be serialized, if it is already a string then it is returned @treturn string The key after it has been serialized @@ -389,11 +389,11 @@ self:write_action('save', 'TestKey', 'Foo') ]] function Datastore:write_action(action, key, value) - local data = {action, self.name, '"'..key..'"'} + local data = {action, self.name, key} if value ~= nil then - data[4] = type(value) == 'table' and '"'..game.table_to_json(value)..'"' or '"'..tostring(value)..'"' + data[4] = type(value) == 'table' and game.table_to_json(value) or tostring(value) end - game.write_file('datastore.out', table.concat(data, ' ')..'\n', true, 0) + game.write_file('ext/datastore.out', table.concat(data, ' ')..'\n', true, 0) end ----- Datastore Local @@ -520,7 +520,7 @@ function Datastore:increment(key, delta) return Datastore:set(key, value + (delta or 1)) end -local function update_error(err) error('An error ocurred in datastore update: '..err, 2) end +local function update_error(err) error('An error ocurred in datastore update: '..trace(err), 2) end --[[-- Use a function to update the value locally, will trigger on_update then on_save, save_to_disk and auto_save is required for on_save @tparam any key The key that you want to apply the update to, must be a string unless a serializer is set @tparam function callback The function that will be used to update the value at this key @@ -560,7 +560,7 @@ function Datastore:remove(key) if self.parent and self.parent.auto_save then return self.parent:save(key) end end -local function filter_error(err) print('An error ocurred in a datastore filter:', err) end +local function filter_error(err) print('An error ocurred in a datastore filter:'..trace(err)) end --[[-- Internal, Used to filter elements from a table @tparam table tbl The table that will have the filter applied to it @tparam[opt] function callback The function that will be used as a filter, if none giving then the provided table is returned @@ -737,7 +737,7 @@ end ----- Events -- @section events -local function event_error(err) print('An error ocurred in a datastore event handler:', err) end +local function event_error(err) print('An error ocurred in a datastore event handler: '..trace(err)) end --[[-- Internal, Raise an event on this datastore @tparam string event_name The name of the event to raise for this datastore @tparam string key The key that this event is being raised for @@ -752,7 +752,7 @@ value = self:raise_event('on_save', key, value) function Datastore:raise_event(event_name, key, value, source) -- Raise the event for the children of this datastore if source ~= 'child' and next(self.children) then - if type(value) ~= 'table' then value = self:raw_get(key, true) end + if type(value) ~= 'table' then value = {} end for value_name, child in pairs(self.children) do value[value_name] = child:raise_event(event_name, key, value[value_name], 'parent') end @@ -769,7 +769,7 @@ function Datastore:raise_event(event_name, key, value, source) -- Raise the event for the parent of this datastore if source ~= 'parent' and self.parent then - self.parent:raise_event(event_name, key, self.parent:raw_get(key), 'child') + self.parent:raise_event(event_name, key, self.parent:raw_get(key, true), 'child') end -- If this is the save event and the table is empty then return nil diff --git a/expcore/player_data.lua b/expcore/player_data.lua index d6157f5c..576674f6 100644 --- a/expcore/player_data.lua +++ b/expcore/player_data.lua @@ -47,13 +47,6 @@ local Datastore = require 'expcore.datastore' --- @dep expcore.datastore local Commands = require 'expcore.commands' --- @dep expcore.commands require 'config.expcore.command_general_parse' --- @dep config.expcore.command_general_parse ---- Stores all the players whos data failed to load -local FailedLoad = {} -global.failed_player_data = FailedLoad -Event.on_load(function() - FailedLoad = global.failed_player_data -end) - --- Common player data that acts as the root store for player data local PlayerData = Datastore.connect('PlayerData', true) -- saveToDisk PlayerData:set_serializer(Datastore.name_serializer) -- use player name @@ -87,11 +80,10 @@ Commands.new_command('save-data', 'Writes all your player data to a file on your game.write_file('expgaming_player_data.json', game.table_to_json(PlayerData:get(player, {})), false, player.index) end) ---- Async function called after 10 seconds with no player data loaded +--- Async function called after 5 seconds with no player data loaded local check_data_loaded = Async.register(function(player) local player_data = PlayerData:get(player) if not player_data then - FailedLoad[player.name] = true player.print{'expcore-data.data-failed'} Datastore.ingest('request', 'PlayerData', player.name, '{"failed_load":true}') end @@ -100,8 +92,8 @@ end) --- When player data loads tell the player if the load had failed previously PlayerData:on_load(function(player_name, player_data) if not player_data or player_data.failed_load then return end - if FailedLoad[player_name] then - FailedLoad[player_name] = nil + local existing_data = PlayerData:get(player_name) + if existing_data and existing_data.failed_load then game.players[player_name].print{'expcore-data.data-restore'} end end) @@ -128,7 +120,7 @@ end) Event.add(defines.events.on_player_joined_game, function(event) local player = game.players[event.player_index] PlayerData:request(player) - Async.wait(600, check_data_loaded, player) + Async.wait(300, check_data_loaded, player) end) --- Unload player data when they leave @@ -136,7 +128,6 @@ Event.add(defines.events.on_player_left_game, function(event) local player = game.players[event.player_index] local player_data = PlayerData:get(player) if player_data.failed_load then - FailedLoad[player.name] = nil PlayerData:raw_set(player) else PlayerData:unload(player) end end) diff --git a/modules/data/bonus.lua b/modules/data/bonus.lua index 6cf1752f..2275d543 100644 --- a/modules/data/bonus.lua +++ b/modules/data/bonus.lua @@ -23,8 +23,8 @@ local function apply_bonus(player, amount) end --- When store is updated apply new bonus to the player -PlayerBonus.on_update(function(player_name, player_bonus) - apply_bonus(game.player[player_name], player_bonus or 0) +PlayerBonus:on_update(function(player_name, player_bonus) + apply_bonus(game.players[player_name], player_bonus or 0) end) --- Changes the amount of bonus you receive diff --git a/modules/data/tag.lua b/modules/data/tag.lua index 644fc0f3..d01b6918 100644 --- a/modules/data/tag.lua +++ b/modules/data/tag.lua @@ -16,7 +16,7 @@ local PlayerTags = PlayerData.Settings:combine('Tag') PlayerTags:on_update(function(player_name, player_tag) local player = game.players[player_name] if player_tag == nil or player_tag == '' then - player_tag.tag = '' + player.tag = '' else player.tag = '- '..player_tag end From 2dacbe9edd3e2e57cc2aba3f3b86887630010f86 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sat, 30 May 2020 01:45:02 +0100 Subject: [PATCH 09/11] Added Statistics --- config/_file_loader.lua | 1 + config/statistics.lua | 29 +++++++++ expcore/datastore.lua | 8 +-- expcore/player_data.lua | 22 ++++--- modules/data/statistics.lua | 123 ++++++++++++++++++++++++++++++++++++ utils/event_core.lua | 13 ++-- 6 files changed, 177 insertions(+), 19 deletions(-) create mode 100644 config/statistics.lua create mode 100644 modules/data/statistics.lua diff --git a/config/_file_loader.lua b/config/_file_loader.lua index 28d4ebde..5fd71d8d 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -43,6 +43,7 @@ return { 'modules.addons.tree-decon', --- Data + 'modules.data.statistics', 'modules.data.player-colours', 'modules.data.greetings', 'modules.data.quickbar', diff --git a/config/statistics.lua b/config/statistics.lua new file mode 100644 index 00000000..d26fa2f8 --- /dev/null +++ b/config/statistics.lua @@ -0,0 +1,29 @@ +--- A list of all tracked statistics and the events which trigger them +-- @config Statistics + +local e = defines.events -- order as per lua api as it was easier just to go down the list +return { + Playtime = true, --- @setting Playtime If playtime is tracked for a player, play time measured in minutes + AfkTime = true, --- @setting AfkTime If afk time is tracked for a player, play time measured in minutes, afk is once a player does nothing for 5 minutes + DistanceTraveled = true, --- @settings DistanceTraveled If distance traveled is checked, only counts if not afk + MachinesRemoved = true, --- @setting MachinesRemoved If removed machines are tracked, includes marked for decon and player mined entity + OreMined = true, --- @settings OreMined If ore mined is tracked for a player, includes player mined entity but only ore, + DamageDealt = true, --- @settings DamageDealt If damage dealt is tracked for a player, includes any damage to entities not on the same force or neutral + Kills = true, --- @settings Kills If kills are tracked for a player, includes all kills not on same force or neutral + counters = { --- @setting counters Simple statistics that just go up by one each time an event happens + MachinesBuilt = e.on_built_entity, + MapTagsMade = e.on_chart_tag_added, + ChatMessages = e.on_console_chat, + CommandsUsed = e.on_console_command, + ItemsPickedUp = e.on_picked_up_item, + TilesBuilt = e.on_player_built_tile, + ItemsCrafted = e.on_player_crafted_item, + MapsPlayed = e.on_player_created, + DeconstructionPlanerUsed = e.on_player_deconstructed_area, + Deaths = e.on_player_died, + JoinCount = e.on_player_joined_game, + TilesRemoved = e.on_player_mined_tile, + CapsulesUsed = e.on_player_used_capsule, + RocketsLaunched = e.on_rocket_launched + } +} \ No newline at end of file diff --git a/expcore/datastore.lua b/expcore/datastore.lua index f13a4c50..ffa23f99 100644 --- a/expcore/datastore.lua +++ b/expcore/datastore.lua @@ -391,7 +391,7 @@ self:write_action('save', 'TestKey', 'Foo') function Datastore:write_action(action, key, value) local data = {action, self.name, key} if value ~= nil then - data[4] = type(value) == 'table' and game.table_to_json(value) or tostring(value) + data[4] = type(value) == 'table' and game.table_to_json(value) or value end game.write_file('ext/datastore.out', table.concat(data, ' ')..'\n', true, 0) end @@ -517,7 +517,7 @@ ExampleData:increment('TestNumber') function Datastore:increment(key, delta) key = self:serialize(key) local value = self:raw_get(key) or 0 - return Datastore:set(key, value + (delta or 1)) + return self:set(key, value + (delta or 1)) end local function update_error(err) error('An error ocurred in datastore update: '..trace(err), 2) end @@ -560,7 +560,7 @@ function Datastore:remove(key) if self.parent and self.parent.auto_save then return self.parent:save(key) end end -local function filter_error(err) print('An error ocurred in a datastore filter:'..trace(err)) end +local function filter_error(err) log('An error ocurred in a datastore filter:'..trace(err)) end --[[-- Internal, Used to filter elements from a table @tparam table tbl The table that will have the filter applied to it @tparam[opt] function callback The function that will be used as a filter, if none giving then the provided table is returned @@ -737,7 +737,7 @@ end ----- Events -- @section events -local function event_error(err) print('An error ocurred in a datastore event handler: '..trace(err)) end +local function event_error(err) log('An error ocurred in a datastore event handler: '..trace(err)) end --[[-- Internal, Raise an event on this datastore @tparam string event_name The name of the event to raise for this datastore @tparam string key The key that this event is being raised for diff --git a/expcore/player_data.lua b/expcore/player_data.lua index 576674f6..c3861a3c 100644 --- a/expcore/player_data.lua +++ b/expcore/player_data.lua @@ -83,26 +83,30 @@ end) --- Async function called after 5 seconds with no player data loaded local check_data_loaded = Async.register(function(player) local player_data = PlayerData:get(player) - if not player_data then + if not player_data or not player_data.valid then player.print{'expcore-data.data-failed'} - Datastore.ingest('request', 'PlayerData', player.name, '{"failed_load":true}') + Datastore.ingest('request', 'PlayerData', player.name, '{"valid":false}') end end) --- When player data loads tell the player if the load had failed previously PlayerData:on_load(function(player_name, player_data) - if not player_data or player_data.failed_load then return end + if not player_data or not player_data.valid then return end local existing_data = PlayerData:get(player_name) - if existing_data and existing_data.failed_load then + if existing_data and existing_data.valid == false then game.players[player_name].print{'expcore-data.data-restore'} end + player_data.valid = true end) --- Remove data that the player doesnt want to have stored PlayerData:on_save(function(player_name, player_data) local dataPreference = DataSavingPreference:get(player_name) dataPreference = PreferenceEnum[dataPreference] - if dataPreference == PreferenceEnum.All then return player_data end + if dataPreference == PreferenceEnum.All then + player_data.valid = nil + return player_data + end local saved_player_data = { PlayerRequired = player_data.PlayerRequired, DataSavingPreference = PreferenceEnum[dataPreference] } if dataPreference <= PreferenceEnum.Settings then saved_player_data.PlayerSettings = player_data.PlayerSettings end @@ -119,17 +123,17 @@ end) --- Load player data when they join Event.add(defines.events.on_player_joined_game, function(event) local player = game.players[event.player_index] - PlayerData:request(player) Async.wait(300, check_data_loaded, player) + PlayerData:request(player) end) --- Unload player data when they leave Event.add(defines.events.on_player_left_game, function(event) local player = game.players[event.player_index] local player_data = PlayerData:get(player) - if player_data.failed_load then - PlayerData:raw_set(player) - else PlayerData:unload(player) end + if player_data.valid == true then + PlayerData:unload(player) + else PlayerData:raw_set(player) end end) ----- Module Return ----- diff --git a/modules/data/statistics.lua b/modules/data/statistics.lua new file mode 100644 index 00000000..65d30fcb --- /dev/null +++ b/modules/data/statistics.lua @@ -0,0 +1,123 @@ + +local Event = require 'utils.event' ---@dep utils.event +local config = require 'config.statistics' ---@dep config.statistics +local floor = math.floor +local afk_required = 5*3600 -- 5 minutes + +--- Stores the statistics on a player +local PlayerData = require 'expcore.player_data' --- @dep expcore.player_data +local AllPlayerData = PlayerData.All +local Statistics = PlayerData.Statistics + +--- Update your statistics with any which happened before the data was valid +Statistics:on_load(function(player_name, player_statistics) + local existing_data = AllPlayerData:get(player_name) + if existing_data and existing_data.valid then return end + local counters = config.counters + for key, value in pairs(Statistics:get(player_name, {})) do + if config[key] or counters[key] then + if not player_statistics[key] then + player_statistics[key] = value + else + player_statistics[key] = player_statistics[key] + value + end + end + end + return player_statistics +end) + +--- Add Playtime and AfkTime if it is enabled +if config.Playtime or config.AfkTime then + local playtime, afk_time + if config.Playtime then playtime = Statistics:combine('Playtime') end + if config.AfkTime then afk_time = Statistics:combine('AfkTime') end + Event.on_nth_tick(3600, function() + if game.tick == 0 then return end + for _, player in pairs(game.connected_players) do + if playtime then playtime:increment(player) end + if afk_time and player.afk_time > afk_required then afk_time:increment(player) end + end + end) +end + +--- Add DistanceTraveled if it is enabled +if config.DistanceTraveled then + local stat = Statistics:combine('DistanceTraveled') + Event.add(defines.events.on_player_changed_position, function(event) + local player = game.players[event.player_index] + if not player.valid or not player.connected or player.afk_time > afk_required then return end + stat:increment(player) + end) +end + +--- Add MachinesRemoved if it is enabled +if config.MachinesRemoved then + local stat = Statistics:combine('MachinesRemoved') + local function on_event(event) + if not event.player_index then return end -- Check player is valid + local player = game.players[event.player_index] + if not player.valid or not player.connected then return end + local entity = event.entity -- Check entity is valid + if not entity.valid or entity.force ~= player.force then return end + stat:increment(player) + end + Event.add(defines.events.on_marked_for_deconstruction, on_event) + Event.add(defines.events.on_player_mined_entity, on_event) +end + +--- Add OreMined if it is enabled +if config.OreMined then + local stat = Statistics:combine('OreMined') + Event.add(defines.events.on_player_mined_entity, function(event) + if not event.player_index then return end -- Check player is valid + local player = game.players[event.player_index] + if not player.valid or not player.connected then return end + local entity = event.entity -- Check entity is valid + if not entity.valid or entity.type ~= 'resource' then return end + stat:increment(player) + end) +end + +--- Add DamageDealt if it is enabled +if config.DamageDealt then + local stat = Statistics:combine('DamageDealt') + Event.add(defines.events.on_entity_damaged, function(event) + local character = event.cause -- Check character is valid + if not character.valid or character.type ~= 'character' then return end + local player = character.player -- Check player is valid + if not player.valid or not player.connected then return end + local entity = event.entity -- Check entity is valid + if not entity.valid or entity.force == player.force or entity.force.name == 'neutral' then return end + stat:increment(player, floor(event.final_damage_amount)) + end) +end + +--- Add Kills if it is enabled +if config.DamageDealt then + local stat = Statistics:combine('Kills') + Event.add(defines.events.on_entity_died, function(event) + local character = event.cause -- Check character is valid + if not character.valid or character.type ~= 'character' then return end + local player = character.player -- Check player is valid + if not player.valid or not player.connected then return end + local entity = event.entity -- Check entity is valid + if not entity.valid or entity.force == player.force or entity.force.name == 'neutral' then return end + stat:increment(player) + end) +end + +--- Add all the remaining statistics from the config +for statistic, event_name in pairs(config.counters) do + local stat = Statistics:combine(statistic) + Event.add(event_name, function(event) + if event.player_index then + local player = game.players[event.player_index] + if not player.valid or not player.connected then return end + stat:increment(player) + else + for _, player in pairs(game.connected_players) do + stat:increment(player) + end + end + end) +end \ No newline at end of file diff --git a/utils/event_core.lua b/utils/event_core.lua index b34715e1..9525167a 100644 --- a/utils/event_core.lua +++ b/utils/event_core.lua @@ -11,11 +11,16 @@ local event_handlers = {} -- map of nth_tick to handlers[] local on_nth_tick_event_handlers = {} -local pcall = pcall +local trace = debug.traceback +local xpcall = xpcall local log = log local script_on_event = script.on_event local script_on_nth_tick = script.on_nth_tick +local function handler_error(err) + log('\n\t'..trace(err)) +end + local function call_handlers(handlers, event) if _DEBUG then for i = 1, #handlers do @@ -24,11 +29,7 @@ local function call_handlers(handlers, event) end else for i = 1, #handlers do - local handler = handlers[i] - local success, error = pcall(handler, event) - if not success then - log('\n\t'..error) - end + xpcall(handlers[i], handler_error, event) end end end From 0af93b9bb5365b678d75b422584be6a4b38cc400 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sat, 30 May 2020 01:55:15 +0100 Subject: [PATCH 10/11] Fixed Doc Issues --- config/statistics.lua | 8 ++++---- expcore/player_data.lua | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/config/statistics.lua b/config/statistics.lua index d26fa2f8..b7058b47 100644 --- a/config/statistics.lua +++ b/config/statistics.lua @@ -5,11 +5,11 @@ local e = defines.events -- order as per lua api as it was easier just to go dow return { Playtime = true, --- @setting Playtime If playtime is tracked for a player, play time measured in minutes AfkTime = true, --- @setting AfkTime If afk time is tracked for a player, play time measured in minutes, afk is once a player does nothing for 5 minutes - DistanceTraveled = true, --- @settings DistanceTraveled If distance traveled is checked, only counts if not afk + DistanceTraveled = true, --- @setting DistanceTraveled If distance traveled is checked, only counts if not afk MachinesRemoved = true, --- @setting MachinesRemoved If removed machines are tracked, includes marked for decon and player mined entity - OreMined = true, --- @settings OreMined If ore mined is tracked for a player, includes player mined entity but only ore, - DamageDealt = true, --- @settings DamageDealt If damage dealt is tracked for a player, includes any damage to entities not on the same force or neutral - Kills = true, --- @settings Kills If kills are tracked for a player, includes all kills not on same force or neutral + OreMined = true, --- @setting OreMined If ore mined is tracked for a player, includes player mined entity but only ore, + DamageDealt = true, --- @setting DamageDealt If damage dealt is tracked for a player, includes any damage to entities not on the same force or neutral + Kills = true, --- @setting Kills If kills are tracked for a player, includes all kills not on same force or neutral counters = { --- @setting counters Simple statistics that just go up by one each time an event happens MachinesBuilt = e.on_built_entity, MapTagsMade = e.on_chart_tag_added, diff --git a/expcore/player_data.lua b/expcore/player_data.lua index c3861a3c..9d8ea963 100644 --- a/expcore/player_data.lua +++ b/expcore/player_data.lua @@ -91,7 +91,7 @@ end) --- When player data loads tell the player if the load had failed previously PlayerData:on_load(function(player_name, player_data) - if not player_data or not player_data.valid then return end + if not player_data or player_data.valid == false then return end local existing_data = PlayerData:get(player_name) if existing_data and existing_data.valid == false then game.players[player_name].print{'expcore-data.data-restore'} From cd56cbe281fa910030131c951ce0fc30c3b64e21 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sat, 30 May 2020 16:23:42 +0100 Subject: [PATCH 11/11] Added trees and reseach to stats --- config/statistics.lua | 8 +++-- modules/data/statistics.lua | 69 ++++++++++++++++++++++--------------- 2 files changed, 47 insertions(+), 30 deletions(-) diff --git a/config/statistics.lua b/config/statistics.lua index b7058b47..36c60da3 100644 --- a/config/statistics.lua +++ b/config/statistics.lua @@ -7,9 +7,12 @@ return { AfkTime = true, --- @setting AfkTime If afk time is tracked for a player, play time measured in minutes, afk is once a player does nothing for 5 minutes DistanceTraveled = true, --- @setting DistanceTraveled If distance traveled is checked, only counts if not afk MachinesRemoved = true, --- @setting MachinesRemoved If removed machines are tracked, includes marked for decon and player mined entity - OreMined = true, --- @setting OreMined If ore mined is tracked for a player, includes player mined entity but only ore, + TreesDestroyed = true, --- @setting OreMined If ore mined is tracked for a player, includes marked for decon and player mined entity but only trees + OreMined = true, --- @setting OreMined If ore mined is tracked for a player, includes player mined entity but only ore DamageDealt = true, --- @setting DamageDealt If damage dealt is tracked for a player, includes any damage to entities not on the same force or neutral Kills = true, --- @setting Kills If kills are tracked for a player, includes all kills not on same force or neutral + RocketsLaunched = true, --- @setting RocketsLaunched If the number of rockets launched should be tracked, done for all players on the force + ResearchCompleted = true, --- @setting ResearchCompleted If the number of researches completed should be tracked, done for all players on the force counters = { --- @setting counters Simple statistics that just go up by one each time an event happens MachinesBuilt = e.on_built_entity, MapTagsMade = e.on_chart_tag_added, @@ -23,7 +26,6 @@ return { Deaths = e.on_player_died, JoinCount = e.on_player_joined_game, TilesRemoved = e.on_player_mined_tile, - CapsulesUsed = e.on_player_used_capsule, - RocketsLaunched = e.on_rocket_launched + CapsulesUsed = e.on_player_used_capsule } } \ No newline at end of file diff --git a/modules/data/statistics.lua b/modules/data/statistics.lua index 65d30fcb..fd554b8b 100644 --- a/modules/data/statistics.lua +++ b/modules/data/statistics.lua @@ -50,34 +50,26 @@ if config.DistanceTraveled then end) end ---- Add MachinesRemoved if it is enabled -if config.MachinesRemoved then - local stat = Statistics:combine('MachinesRemoved') +--- Add MachinesRemoved and TreesDestroyed and config.OreMined if it is enabled +if config.MachinesRemoved or config.TreesDestroyed or config.OreMined then + local machines, trees, ore + if config.MachinesRemoved then machines = Statistics:combine('MachinesRemoved') end + if config.TreesDestroyed then trees = Statistics:combine('TreesDestroyed') end + if config.OreMined then ore = Statistics:combine('OreMined') end local function on_event(event) if not event.player_index then return end -- Check player is valid local player = game.players[event.player_index] if not player.valid or not player.connected then return end local entity = event.entity -- Check entity is valid - if not entity.valid or entity.force ~= player.force then return end - stat:increment(player) + if not entity.valid then return end + if entity.type == 'resource' then ore:increment(player) + elseif entity.type == 'tree' then trees:increment(player) + elseif entity.force == player.force then machines:increment(player) end end Event.add(defines.events.on_marked_for_deconstruction, on_event) Event.add(defines.events.on_player_mined_entity, on_event) end ---- Add OreMined if it is enabled -if config.OreMined then - local stat = Statistics:combine('OreMined') - Event.add(defines.events.on_player_mined_entity, function(event) - if not event.player_index then return end -- Check player is valid - local player = game.players[event.player_index] - if not player.valid or not player.connected then return end - local entity = event.entity -- Check entity is valid - if not entity.valid or entity.type ~= 'resource' then return end - stat:increment(player) - end) -end - --- Add DamageDealt if it is enabled if config.DamageDealt then local stat = Statistics:combine('DamageDealt') @@ -106,18 +98,41 @@ if config.DamageDealt then end) end +--- Add RocketsLaunched if it is enabled +if config.RocketsLaunched then + local stat = Statistics:combine('RocketsLaunched') + Event.add(defines.events.on_rocket_launched, function(event) + local silo = event.rocket_silo -- Check silo is valid + if not silo or not silo.valid then return end + local force = silo.force -- Check force is valid + if not force or not force.valid then return end + for _, player in pairs(force.connected_players) do + stat:increment(player) + end + end) +end + +--- Add RocketsLaunched if it is enabled +if config.ResearchCompleted then + local stat = Statistics:combine('ResearchCompleted') + Event.add(defines.events.on_research_finished, function(event) + local research = event.research -- Check research is valid + if event.by_script or not research or not research.valid then return end + local force = research.force -- Check force is valid + if not force or not force.valid then return end + for _, player in pairs(force.connected_players) do + stat:increment(player) + end + end) +end + --- Add all the remaining statistics from the config for statistic, event_name in pairs(config.counters) do local stat = Statistics:combine(statistic) Event.add(event_name, function(event) - if event.player_index then - local player = game.players[event.player_index] - if not player.valid or not player.connected then return end - stat:increment(player) - else - for _, player in pairs(game.connected_players) do - stat:increment(player) - end - end + if not event.player_index then return end + local player = game.players[event.player_index] + if not player.valid or not player.connected then return end + stat:increment(player) end) end \ No newline at end of file