• R/O
  • HTTP
  • SSH
  • HTTPS

コミット

タグ

よく使われているワード(クリックで追加)

javaandroidc++linuxc#objective-ccocoa誰得qtrubybathyscaphegamephpguiwindowsc翻訳pythonomegattwitterframeworkbtronarduinovb.net計画中(planning stage)directxpreviewertestゲームエンジンdom

Administrator's Toolkit VS plugin


コミットメタ情報

リビジョン05cb4bd9a994b500b09a315b0f17bc1136329b24 (tree)
日時2019-08-12 13:15:24
作者melchior <melchior@user...>
コミッターmelchior

ログメッセージ

Created automatic backup system,
added proxy use for server side use

変更サマリ

差分

--- /dev/null
+++ b/AdminToolkit/AdminModCommand.cs
@@ -0,0 +1,38 @@
1+using System;
2+
3+using Vintagestory.API.Server;
4+using Vintagestory.API.Common;
5+
6+
7+
8+namespace AdminToolkit
9+{
10+ public abstract class AdminModCommand : ServerChatCommand
11+ {
12+ protected ICoreServerAPI ServerAPI;
13+ protected ILogger Logger;
14+
15+
16+ protected AdminModCommand(ICoreServerAPI _serverAPI)
17+ {
18+ ServerAPI = _serverAPI;
19+ Logger = ServerAPI.World.Logger;
20+ }
21+
22+ AdminModCommand( )
23+ {
24+ throw new NotSupportedException( );
25+ }
26+
27+ /// <summary>
28+ /// Gets or sets the cached configuration.
29+ /// </summary>
30+ /// <value>The cached configuration.</value>
31+ internal AdminModConfig CachedConfiguration {
32+ get {
33+ return ( AdminModConfig )ServerAPI.ObjectCache[AdminToolkit._configFilename];
34+ }
35+ }
36+ }
37+}
38+
--- a/AdminToolkit/AdminModConfig.cs
+++ b/AdminToolkit/AdminModConfig.cs
@@ -1,42 +1,51 @@
11 using System;
22
3-using ProtoBuf;
43
54
65 namespace AdminToolkit
76 {
8- [ProtoContract]
7+ /// <summary>
8+ /// POCO for config settings
9+ /// </summary>
910 internal class AdminModConfig
1011 {
1112 /// <summary>
1213 /// The Role to constrain players with until rule acceptance
1314 /// </summary>
14- [ProtoMember(0)]
1515 public string PlayerRoleRestrain { get; set; }
1616
1717 /// <summary>
1818 /// The Role to transition players after rule acceptance
1919 /// </summary>
20- [ProtoMember(1)]
2120 public string PlayerRoleNormal { get; set; }
2221
2322 /// <summary>
2423 /// Sets rule role changer swapping behavior on/off.
2524 /// </summary>
2625 /// <value>If rule role changer should be enabled.</value>
27- [ProtoMember(2)]
2826 public bool RuleRoleChangerEnabled { get; set; }
2927
28+ /// <summary>
29+ /// Time to wait between backup windows
30+ /// </summary>
31+ /// <value>The backup delay.</value>
32+ public TimeSpan BackupDelay { get; set;}
3033
31- /*
32- * "DefaultRoleCode": "suplayer",
33- */
34+ /// <summary>
35+ /// Number of full backup files to keep (older get deleted first)
36+ /// </summary>
37+ /// <value>The backup count.</value>
38+ public uint BackupCount { get; set;}
3439
3540 public AdminModConfig( )
3641 {
3742 this.PlayerRoleRestrain = "suvisitor";
3843 this.PlayerRoleNormal = "suplayer";
3944 this.RuleRoleChangerEnabled = false;
45+
46+ this.BackupDelay = new TimeSpan(1, 0, 0);
47+ this.BackupCount = 10;
48+
4049 }
4150
4251
--- a/AdminToolkit/AdminToolkit.csproj
+++ b/AdminToolkit/AdminToolkit.csproj
@@ -61,16 +61,24 @@
6161 <HintPath>VS_libs\protobuf-net.dll</HintPath>
6262 <Private>False</Private>
6363 </Reference>
64+ <Reference Include="VintagestoryLib">
65+ <HintPath>VS_libs\VintagestoryLib.dll</HintPath>
66+ <Private>False</Private>
67+ </Reference>
6468 </ItemGroup>
6569 <ItemGroup>
6670 <Compile Include="AdminToolkitMod.cs" />
6771 <Compile Include="Properties\AssemblyInfo.cs" />
68- <Compile Include="AdminListingCommand.cs" />
69- <Compile Include="RulesCommand.cs" />
7072 <Compile Include="AdminModConfig.cs" />
73+ <Compile Include="AdminModCommand.cs" />
74+ <Compile Include="Commands\AdminListingCommand.cs" />
75+ <Compile Include="Commands\BackupCycleCommand.cs" />
76+ <Compile Include="Commands\RulesCommand.cs" />
77+ <Compile Include="MechTurk.cs" />
7178 </ItemGroup>
7279 <ItemGroup>
7380 <Folder Include="VS_libs\" />
81+ <Folder Include="Commands\" />
7482 </ItemGroup>
7583 <ItemGroup>
7684 <None Include="modinfo.json">
--- a/AdminToolkit/AdminToolkitMod.cs
+++ b/AdminToolkit/AdminToolkitMod.cs
@@ -23,7 +23,7 @@ namespace AdminToolkit
2323 * Optional: ACCEPTANCE / REJECT of server rules {changes players role}
2424 * List all Admins (online or offline) & track last logoff date
2525 * { Alter ADMIN text to look 'different' }
26- * Offline Admin Notify TODO?
26+ * Cyclic automatic Backups
2727 */
2828
2929 private ICoreAPI API { get; set; }
@@ -90,9 +90,9 @@ namespace AdminToolkit
9090 PopulateAdminRoleTable( );
9191 PrepareServersideConfig( );
9292
93- this.ServerAPI.RegisterCommand(new RulesCommand(this.ServerAPI));
93+ this.ServerAPI.RegisterCommand(new RulesCommand(this.ServerAPI) );
9494 this.ServerAPI.RegisterCommand(new AdminListingCommand(this.ServerAPI) );
95- this.ServerAPI.RegisterCommand("say", "Say/Announce with Formated text", string.Empty, Say, Privilege.commandplayer);
95+ this.ServerAPI.RegisterCommand(new BackupCycleCommand(this.ServerAPI) );
9696
9797 this.ServerAPI.Event.PlayerChat += BoomingVoiceOfAuthority;
9898 }
@@ -113,7 +113,21 @@ namespace AdminToolkit
113113 }
114114 }
115115
116+ private void PrepareServersideConfig( )
117+ {
118+ AdminModConfig config = ServerAPI.LoadModConfig<AdminModConfig>(_configFilename);
119+
120+ if (config == null) {
121+ //Regen default
122+ Mod.Logger.Warning("Regenerating default config as it was missing / unparsable...");
123+ ServerAPI.StoreModConfig<AdminModConfig>(new AdminModConfig( ), _configFilename);
124+ config = ServerAPI.LoadModConfig<AdminModConfig>(_configFilename);
125+ }
116126
127+ this.CachedConfiguration = config;
128+
129+ if (this.CachedConfiguration.RuleRoleChangerEnabled) { Mod.Logger.Notification("Admin toolkit; Role change on Rule accept: * ENABLED *"); }
130+ }
117131
118132 /// <summary>
119133 /// Makes Administrator text messages appear 'different'
@@ -143,90 +157,10 @@ namespace AdminToolkit
143157 return message;
144158 }
145159
146- private void PrepareServersideConfig( )
147- {
148- AdminModConfig config = ServerAPI.LoadModConfig<AdminModConfig>(_configFilename);
149-
150- if (config == null) {
151- //Regen default
152- Mod.Logger.Warning("Regenerating default config as it was missing / unparsable...");
153- ServerAPI.StoreModConfig<AdminModConfig>(new AdminModConfig( ), _configFilename);
154- config = ServerAPI.LoadModConfig<AdminModConfig>(_configFilename);
155- }
156-
157- this.CachedConfiguration = config;
158-
159- if (this.CachedConfiguration.RuleRoleChangerEnabled) { Mod.Logger.Notification("Admin toolkit; Role change on Rule accept: * ENABLED *"); }
160- }
161-
162- /// <summary>
163- /// Say the formated text to a specific player / group / all
164- /// </summary>
165- /// <param name="player">Player.</param>
166- /// <param name="groupId">Group identifier.</param>
167- /// <param name="args">Arguments.</param>
168- private void Say(IServerPlayer player, int groupId, CmdArgs args)
169- {
170- if (args.Length > 0) {
171-
172- string first = args.PopWord( );
173- string message, name, group_name;
174- int? group_number;
175160
176- switch (first)
177- {
178- case "*all*":
179- message = args.PopAll( );
180161
181- ServerAPI.BroadcastMessageToAllGroups(message, EnumChatType.Notification);//Check: if it preserves format!
182-
183- break;
184-
185- case "name":
186-
187- name = args.PopWord( ); //Quotes?
188- message = args.PopAll( ); //Ugh - QUOTES?!
189-
190- IPlayer playerByName = ServerAPI.World.AllOnlinePlayers.FirstOrDefault(plr => string.Compare(plr.PlayerName, name, StringComparison.OrdinalIgnoreCase) == 0);
191-
192- if (playerByName != null)
193- {
194- ServerAPI.SendMessage(playerByName, GlobalConstants.CurrentChatGroup, message, EnumChatType.OthersMessage);
195- }
196- else
197- {
198- player.SendMessage(GlobalConstants.CurrentChatGroup, $"No player found by name '{name}'", EnumChatType.CommandError);
199- }
200162
201- break;
202163
203- case "group-name":
204-
205- group_name = args.PopWord( );//More quotes?!
206- message = args.PopAll( ); //Ugh - QUOTES?!
207-
208- //GET: PlayerGroupMembership list or number by name
209-
210- //ServerAPI.SendMessageToGroup(0, message, EnumChatType.OthersMessage );
211-
212- break;
213-
214- case "group-number":
215- group_number = args.PopInt();
216- message = args.PopAll( ); //Ugh - QUOTES?!
217-
218- ServerAPI.SendMessageToGroup(group_number.Value,message, EnumChatType.OthersMessage );
219-
220- break;
221-
222- default:
223- player.SendMessage(GlobalConstants.CurrentChatGroup, @"/Say command not formated correctly.", EnumChatType.CommandError);
224- break;
225- }
226-
227-
228- }
229- }
230164
231165
232166
--- a/AdminToolkit/AdminListingCommand.cs
+++ b/AdminToolkit/Commands/AdminListingCommand.cs
@@ -9,21 +9,16 @@ using Vintagestory.API.Common;
99
1010 namespace AdminToolkit
1111 {
12- public class AdminListingCommand : ServerChatCommand
13- {
14- private ICoreServerAPI ServerAPI;
15-
16- public AdminListingCommand(ICoreServerAPI _serverAPI )
17- {
18- ServerAPI = _serverAPI;
12+ public class AdminListingCommand : AdminModCommand
13+ {
14+ public AdminListingCommand(ICoreServerAPI _serverAPI ): base(_serverAPI)
15+ {
1916 this.Command = "admins";
2017 this.Description = "List of Server Administrators";
2118 this.handler += AdminsitratorListing;
2219 }
2320
2421
25-
26-
2722 private void AdminsitratorListing(IServerPlayer player, int groupId, CmdArgs args)
2823 {
2924 player.SendMessage(groupId, "Listing Administrators:", EnumChatType.CommandSuccess);
--- /dev/null
+++ b/AdminToolkit/Commands/BackupCycleCommand.cs
@@ -0,0 +1,177 @@
1+using System;
2+using System.Text;
3+using System.IO;
4+using System.Linq;
5+
6+
7+using Vintagestory.API.Common;
8+using Vintagestory.API.Config;
9+using Vintagestory.API.Server;
10+
11+using Vintagestory.Server;
12+
13+namespace AdminToolkit
14+{
15+ public class BackupCycleCommand : AdminModCommand
16+ {
17+ private long backupTickerID;
18+ private const string _timeFormat = @"d\D\ hh\H\ mm\M\ ss\S";
19+ private MechTurk mechanicalTurk;
20+
21+ public BackupCycleCommand(ICoreServerAPI _serverAPI) : base(_serverAPI)
22+ {
23+ this.Command = "backups";
24+ this.Description = "Control server automatic backup cycle.";
25+ this.handler += BackupCommandParser;
26+ this.RequiredPrivilege = Privilege.controlserver;//"Backup" ?
27+ this.Syntax = "enable / disable / delay [hours] / stats";
28+
29+ mechanicalTurk = new MechTurk(ServerAPI.Server.Config.Roles.Find(ro => ro.Code == "admin"), this.Logger);
30+ }
31+
32+ private void BackupCommandParser(IServerPlayer player, int groupId, CmdArgs args)
33+ {
34+ //Enable/Disable, time rate, count of files & status
35+
36+ StringBuilder msgLine = new StringBuilder( );
37+ bool success = false;
38+ int? delay;
39+
40+ if (args.Length > 0) {
41+ string command = args.PopWord( );
42+
43+ if (command.Length > 0) {
44+ command = command.ToLowerInvariant( );
45+ }
46+
47+ switch (command) {
48+ case "enable":
49+ success = EnableBackupCycle(true);
50+ if (success) msgLine.AppendFormat("Enabled, with delay: {0}\n", this.CachedConfiguration.BackupDelay.ToString(_timeFormat));
51+ break;
52+
53+ case "disable":
54+ success = EnableBackupCycle(false);
55+ if (success) msgLine.AppendLine("Disabled.");
56+ break;
57+
58+ case "delay":
59+ delay = args.PopInt( );
60+
61+ if (delay.HasValue && delay.Value >= 1) {
62+ AlterTimeDelay(delay.Value);
63+ msgLine.AppendFormat("Changed delay to: {0} ", this.CachedConfiguration.BackupDelay.ToString(_timeFormat));
64+ success = true;
65+ } else {
66+ msgLine.AppendLine("Wrong time delay value; must be positive integer 1 or more (hours) ");
67+ }
68+
69+ break;
70+
71+ case "stats":
72+
73+
74+
75+ break;
76+
77+ default:
78+ msgLine.AppendLine("Unknown parameter");
79+ break;
80+ }
81+
82+
83+
84+ } else {
85+ msgLine.AppendLine("supply more command arguments; enable / disable / stats / delay ");
86+ }
87+
88+
89+
90+
91+ player.SendMessage(groupId, msgLine.ToString( ), success ? EnumChatType.CommandSuccess : EnumChatType.CommandError);
92+ }
93+
94+ private bool EnableBackupCycle(bool enable)
95+ {
96+ if (enable)
97+ {
98+ if (backupTickerID == 0)
99+ {
100+ this.backupTickerID = ServerAPI.Event.RegisterCallback(BackupCycleHandler, (int)this.CachedConfiguration.BackupDelay.TotalMilliseconds);
101+ Logger.VerboseDebug("BackupCycle enabled, delay: {0}", this.CachedConfiguration.BackupDelay.ToString(_timeFormat));
102+ return true;
103+ }
104+ }
105+ else
106+ {
107+ if (backupTickerID != 0)
108+ {
109+ ServerAPI.Event.UnregisterCallback(backupTickerID);
110+ Logger.VerboseDebug("BackupCycle disabled");
111+ return true;
112+ }
113+ }
114+
115+ return false;
116+ }
117+
118+
119+ private void BackupCycleHandler(float elapsed)
120+ {
121+ Logger.Event("Automatic Backup triggered, elasped {0} @{1} Uptime",elapsed, ServerAPI.Server.ServerUptimeSeconds );
122+ //Peek at backup DIR, count files of the backup type
123+ var backupDir = new DirectoryInfo(GamePaths.Backups);
124+
125+ if (backupDir.Exists) {
126+ var files = backupDir.GetFiles("*" + GlobalConstants.WorldSaveExtension);
127+
128+ if (files.Length > this.CachedConfiguration.BackupCount) {
129+ Logger.VerboseDebug("There are {0} backup files, over set limit", files.Length);
130+ var oldest = files.OrderByDescending(fi => fi.CreationTimeUtc).FirstOrDefault( );
131+
132+ if (oldest != null) {
133+ Logger.VerboseDebug("Oldest backup file: {0}", oldest.Name);
134+ oldest.Delete( );
135+ Logger.Notification("Deleted old Backup: {0}", oldest.FullName);
136+ }
137+ }
138+ } else
139+ {
140+ Logger.VerboseDebug("Could not open backup directory");
141+ }
142+
143+
144+ if (ServerAPI.World is ServerMain) {
145+
146+ ServerMain serverMain = ServerAPI.World as ServerMain;
147+ serverMain.EventManager.TriggerChatCommand(mechanicalTurk, GlobalConstants.ServerInfoChatGroup, @"genbackup", new CmdArgs( ));
148+
149+ } else
150+ {
151+ Logger.Warning("Could not invoke backup command - API (implimentation) has changed, Contact Developer!");
152+ }
153+
154+
155+ //GlobalConstants.ConsoleGroup
156+ /*
157+ backupFileName = Path.GetFileName(server.Config.WorldConfig.SaveFileLocation).Replace(GlobalConstants.WorldSaveExtension, "") + "-" + string.Format("{0:yyyy-MM-dd_HH-mm-ss}", DateTime.Now) + GlobalConstants.WorldSaveExtension;
158+ */
159+ }
160+
161+ private void AlterTimeDelay(int delay)
162+ {
163+ delay = Math.Max(delay, 1);
164+ delay = Math.Min(delay, 500);//Limited by callback set in milliseconds
165+
166+ this.CachedConfiguration.BackupDelay = new TimeSpan(delay, 0, 0);
167+ }
168+
169+ private void UseAMacro( )
170+ {
171+
172+ }
173+ }
174+
175+
176+}
177+
--- a/AdminToolkit/RulesCommand.cs
+++ b/AdminToolkit/Commands/RulesCommand.cs
@@ -12,7 +12,7 @@ using Vintagestory.API.Config;
1212
1313 namespace AdminToolkit
1414 {
15- public class RulesCommand : ServerChatCommand
15+ public class RulesCommand : AdminModCommand
1616 {
1717
1818 private const string _rulesPathKey = @"Rules";
@@ -24,14 +24,9 @@ namespace AdminToolkit
2424
2525 private bool rolesAreValid;
2626
27- private ICoreServerAPI ServerAPI;
28- private ILogger Logger;
29-
30- public RulesCommand(ICoreServerAPI _serverAPI)
31- {
32- ServerAPI = _serverAPI;
33- Logger = ServerAPI.World.Logger;
3427
28+ public RulesCommand(ICoreServerAPI _serverAPI) : base(_serverAPI)
29+ {
3530 PreloadRulesText( );
3631 ValidateAllRolesExist( );
3732
@@ -42,17 +37,6 @@ namespace AdminToolkit
4237 this.ServerAPI.Event.PlayerJoin += UponJoin;
4338 }
4439
45- /// <summary>
46- /// Gets or sets the cached configuration.
47- /// </summary>
48- /// <value>The cached configuration.</value>
49- internal AdminModConfig CachedConfiguration {
50- get {
51- return ( AdminModConfig )ServerAPI.ObjectCache[AdminToolkit._configFilename];
52- }
53- }
54-
55-
5640 private void PreloadRulesText( )
5741 {
5842 Rules = new Dictionary<string, List<string>>( );
--- /dev/null
+++ b/AdminToolkit/MechTurk.cs
@@ -0,0 +1,194 @@
1+using System;
2+using System.Collections.Generic;
3+
4+using Vintagestory.API.Common;
5+using Vintagestory.API.Common.Entities;
6+using Vintagestory.API.Server;
7+
8+namespace AdminToolkit
9+{
10+ public class MechTurk: IPlayer, IServerPlayer
11+ {
12+ private ILogger Logger;
13+
14+ public MechTurk( IPlayerRole role, ILogger logger)
15+ {
16+ this.Role = role;
17+ Logger = logger;
18+ }
19+
20+ public int ClientId {
21+ get {
22+ return -1;
23+ }
24+ }
25+
26+ public EnumClientState ConnectionState {
27+ get {
28+ return EnumClientState.Connected;
29+ }
30+ }
31+
32+ public BlockSelection CurrentBlockSelection {
33+ get {
34+ throw new NotImplementedException( );
35+ }
36+ }
37+
38+ public int CurrentChunkSentRadius {
39+ get {
40+ throw new NotImplementedException( );
41+ }
42+
43+ set {
44+ throw new NotImplementedException( );
45+ }
46+ }
47+
48+ public EntitySelection CurrentEntitySelection {
49+ get {
50+ throw new NotImplementedException( );
51+ }
52+ }
53+
54+ public List<Entitlement> Entitlements {
55+ get {
56+ throw new NotImplementedException( );
57+ }
58+ }
59+
60+ public EntityPlayer Entity {
61+ get {
62+ throw new NotImplementedException( );
63+ }
64+ }
65+
66+ public PlayerGroupMembership[] Groups {
67+ get {
68+ throw new NotImplementedException( );
69+ }
70+ }
71+
72+ public IPlayerInventoryManager InventoryManager {
73+ get {
74+ throw new NotImplementedException( );
75+ }
76+ }
77+
78+ public string IpAddress {
79+ get {
80+ return @"127.0.0.1";
81+ }
82+ }
83+
84+ public float Ping {
85+ get {
86+ return 0.0f;
87+ }
88+ }
89+
90+ public string PlayerName {
91+ get {
92+ return @"Mechanical Turk";
93+ }
94+ }
95+
96+ public string PlayerUID {
97+ get {
98+ return @"console";//Keeps 'ServerEventManager' satisfied
99+ }
100+ }
101+
102+ public string[] Privileges {
103+ get {
104+ return new[]{
105+ Privilege.buildblockseverywhere,
106+ Privilege.useblockseverywhere,
107+ Privilege.gamemode,
108+ Privilege.pickingrange,
109+ Privilege.kick,
110+ Privilege.ban,
111+ Privilege.whitelist,
112+ Privilege.setwelcome,
113+ Privilege.announce,
114+ Privilege.readlists,
115+ Privilege.give,
116+ Privilege.setspawn,
117+ Privilege.controlserver,
118+ Privilege.tp,
119+ Privilege.time,
120+ Privilege.grantrevoke,
121+ Privilege.root,
122+ Privilege.commandplayer,};
123+ }
124+ }
125+
126+ public IPlayerRole Role {
127+ get; private set;
128+ }
129+
130+ public IServerPlayerData ServerData {
131+ get {
132+ throw new NotImplementedException( );
133+ }
134+ }
135+
136+ public EntityPos SpawnPosition {
137+ get {
138+ throw new NotImplementedException( );
139+ }
140+ }
141+
142+ public IWorldPlayerData WorldData {
143+ get {
144+ throw new NotImplementedException( );
145+ }
146+ }
147+
148+ public void BroadcastPlayerData( )
149+ {
150+
151+ }
152+
153+ public void ClearSpawnPosition( )
154+ {
155+ throw new NotImplementedException( );
156+ }
157+
158+ public void Disconnect( )
159+ {
160+ throw new NotImplementedException( );
161+ }
162+
163+ public void Disconnect(string message)
164+ {
165+ throw new NotImplementedException( );
166+ }
167+
168+ public bool HasPrivilege(string privilegeCode)
169+ {
170+ return true;//Robot can do anything
171+ }
172+
173+ public void SendIngameError(string code, string message = null, params object[] langparams)
174+ {
175+
176+ }
177+
178+ public void SendMessage(int groupId, string message, EnumChatType chatType, string data = null)
179+ {
180+ Logger.Chat("®TURK: «{0}»",message);
181+ }
182+
183+ public void SendPositionToClient( )
184+ {
185+ throw new NotImplementedException( );
186+ }
187+
188+ public void SetSpawnPosition(PlayerSpawnPos pos)
189+ {
190+ throw new NotImplementedException( );
191+ }
192+ }
193+}
194+
--- a/AdminToolkit/modinfo.json
+++ b/AdminToolkit/modinfo.json
@@ -1,9 +1,9 @@
11 {
22 "type": "code",
33 "name": "Administrator's Toolkit mod",
4- "description" : "Provides misc. Admin functions; list admins, prints rules / accept rules, ect...",
4+ "description" : "Provides misc. Admin functions;\n list admins, print & accept rules , auto-backup...",
55 "authors": ["Melchior", ],
6- "version": "0.2.0",
6+ "version": "0.3.0",
77 "dependencies": {
88 "game": "1.10.0"
99 },