• R/O
  • HTTP
  • SSH
  • HTTPS

コミット

タグ

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

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

Administrator's Toolkit VS plugin


コミットメタ情報

リビジョン245ab737999e5a79ce2d1b23fc0d53db5fb8995e (tree)
日時2019-08-01 08:34:43
作者melchior <melchior@user...>
コミッターmelchior

ログメッセージ

role change code added *untested*
version update(s)

変更サマリ

差分

--- a/AdminToolkit/AdminListingCommand.cs
+++ b/AdminToolkit/AdminListingCommand.cs
@@ -22,6 +22,8 @@ namespace AdminToolkit
2222 }
2323
2424
25+
26+
2527 private void AdminsitratorListing(IServerPlayer player, int groupId, CmdArgs args)
2628 {
2729 player.SendMessage(groupId, "Listing Administrators:", EnumChatType.CommandSuccess);
--- /dev/null
+++ b/AdminToolkit/AdminModConfig.cs
@@ -0,0 +1,36 @@
1+using System;
2+
3+using ProtoBuf;
4+
5+
6+namespace AdminToolkit
7+{
8+ [ProtoContract]
9+ internal class AdminModConfig
10+ {
11+ /// <summary>
12+ /// The Role to constrain players with until rule acceptance
13+ /// </summary>
14+ [ProtoMember(0)]
15+ public string PlayerRoleRestrain { get; set; }
16+
17+ /// <summary>
18+ /// The Role to transition players after rule acceptance
19+ /// </summary>
20+ [ProtoMember(1)]
21+ public string PlayerRoleNormal { get; set; }
22+
23+ /*
24+ * "DefaultRoleCode": "suplayer",
25+ */
26+
27+ public AdminModConfig( )
28+ {
29+ this.PlayerRoleRestrain = "suvisitor";
30+ this.PlayerRoleNormal = "suplayer";
31+ }
32+
33+
34+ }
35+}
36+
--- a/AdminToolkit/AdminToolkit.csproj
+++ b/AdminToolkit/AdminToolkit.csproj
@@ -57,11 +57,17 @@
5757 <Private>False</Private>
5858 </Reference>
5959 <Reference Include="System.Drawing" />
60+ <Reference Include="protobuf-net">
61+ <HintPath>VS_libs\protobuf-net.dll</HintPath>
62+ <Private>False</Private>
63+ </Reference>
6064 </ItemGroup>
6165 <ItemGroup>
6266 <Compile Include="AdminToolkitMod.cs" />
6367 <Compile Include="Properties\AssemblyInfo.cs" />
6468 <Compile Include="AdminListingCommand.cs" />
69+ <Compile Include="RulesCommand.cs" />
70+ <Compile Include="AdminModConfig.cs" />
6571 </ItemGroup>
6672 <ItemGroup>
6773 <Folder Include="VS_libs\" />
--- a/AdminToolkit/AdminToolkitMod.cs
+++ b/AdminToolkit/AdminToolkitMod.cs
@@ -20,10 +20,10 @@ namespace AdminToolkit
2020 /* Things it should do:
2121 * ==============
2222 * Server RULES Printout {richtext / multi-linugual }
23- * Optional: ACCEPTANCE / REJECT of server rules {changes players game-mode / role?}
24- * List all Admins (online or offline) -track last logoff date
23+ * Optional: ACCEPTANCE / REJECT of server rules {changes players role}
24+ * List all Admins (online or offline) & track last logoff date
2525 * { Alter ADMIN text to look 'different' }
26- * Offline Admin Notify?
26+ * Offline Admin Notify TODO?
2727 */
2828
2929 private ICoreAPI API { get; set; }
@@ -50,21 +50,29 @@ namespace AdminToolkit
5050 Privilege.commandplayer,
5151 };
5252
53- private const string _ruleAcceptKey = @"RulesAccepted";
5453 internal const string _lastLoginKey = @"LastLogin";
55- private const string _rulesPathKey = @"Rules";
56- private const string _acceptKeyword = @"accept";
57-
58- internal static List<string> AdminRoles;
59- private string RulesPath;
60- private Dictionary<string, List<string>> Rules;
54+ internal const string _configFilename = @"admintoolkit.json";
6155
56+ internal static List<string> AdminRoles;
6257
6358 public AdminToolkit( )
6459 {
6560
6661 }
6762
63+ /// <summary>
64+ /// Gets or sets the cached configuration.
65+ /// </summary>
66+ /// <value>The cached configuration.</value>
67+ internal AdminModConfig CachedConfiguration {
68+ get {
69+ return ( AdminModConfig )ServerAPI.ObjectCache[_configFilename];
70+ }
71+ set {
72+ ServerAPI.ObjectCache.Add(_configFilename, value);
73+ }
74+ }
75+
6876 public override bool ShouldLoad(EnumAppSide forSide)
6977 {
7078 return forSide.IsServer( );
@@ -80,91 +88,15 @@ namespace AdminToolkit
8088 this.ServerAPI = API as ICoreServerAPI;
8189
8290 PopulateAdminRoleTable( );
83- PreloadRulesText( );
84-
91+ PrepareServersideConfig( );
8592
86- this.ServerAPI.RegisterCommand("rules", "Server Rules", "[accept]", ServerRulesCommand);
93+ this.ServerAPI.RegisterCommand(new RulesCommand(this.ServerAPI));
8794 this.ServerAPI.RegisterCommand(new AdminListingCommand(this.ServerAPI) );
8895 this.ServerAPI.RegisterCommand("say", "Say/Announce with Formated text", string.Empty, Say, Privilege.commandplayer);
8996
90- this.ServerAPI.Event.PlayerJoin += UponJoin;
9197 this.ServerAPI.Event.PlayerChat += BoomingVoiceOfAuthority;
92-
93-
94-
9598 }
9699
97- /// <summary>
98- /// rules command
99- /// </summary>
100- /// <returns>The rules command.</returns>
101- /// <param name="player">Player.</param>
102- /// <param name="groupId">Group identifier.</param>
103- /// <param name="args">Arguments.</param>
104- private void ServerRulesCommand(IServerPlayer player, int groupId, CmdArgs args)
105- {
106- //Full printout of RULES file.
107- //also Used for formally accepting the rules... should be logged - when accepting
108-
109- if (args.Length == 1) {
110- string word = args.PopWord( );
111- if (string.Compare(_acceptKeyword, word, StringComparison.InvariantCultureIgnoreCase) == 0) {
112-
113- if (CheckRuleAccepted(player) == false) {
114- player.SendMessage(groupId, $"{player.PlayerName} YOU HAVE ACCEPTED RULES!", EnumChatType.CommandSuccess);
115- player.ServerData.CustomPlayerData[_ruleAcceptKey] = true.ToString( );
116- ServerAPI.Server.LogNotification($"Player:{player.PlayerName} UID: {player.PlayerUID} HAS ACCEPTED RULES @ {DateTime.Now.ToShortDateString( )}");
117- } else
118- {
119- player.SendMessage(groupId, $"{player.PlayerName} ALREADY ACCEPTED RULES!", EnumChatType.CommandSuccess);
120- }
121- } else {
122- player.SendMessage(groupId, $"{player.PlayerName} type in chat console: /rules {_acceptKeyword}", EnumChatType.CommandError);
123- }
124-
125- } else {
126- var targetLocale = "en";//TODO: actually get locale!
127-
128- if (Rules.ContainsKey(targetLocale)) {
129-
130- //TODO: rate limit for large files?
131- foreach (var line in Rules[targetLocale]) {
132- player.SendMessage(groupId, line, EnumChatType.OthersMessage);
133- }
134- } else {
135- player.SendMessage(groupId, "* MISSING RULES FILE ! *", EnumChatType.CommandError);
136- }
137- }
138- }
139-
140- /// <summary>
141- /// Send Rule info text or Admin welcome
142- /// </summary>
143- /// <param name="byPlayer">By player.</param>
144- private void UponJoin(IServerPlayer byPlayer)
145- {
146- if (AdminRoles.Contains(byPlayer.Role.Code)) {
147- //Annonce to all Admin\Moderator is here.
148-
149- StringBuilder adminMessage = new StringBuilder( );
150-
151- adminMessage.AppendFormat("<font color='{1}' weight='bold'>«{0}» ̠{2}̠ </font> Present.", byPlayer.Role.Name, byPlayer.Role.Color.Name, byPlayer.PlayerName);
152-
153- ServerAPI.SendMessageToGroup(GlobalConstants.AllChatGroups, adminMessage.ToString(), EnumChatType.AllGroups);
154-
155- byPlayer.ServerData.CustomPlayerData[_lastLoginKey] = DateTimeOffset.UtcNow.ToString("u");
156-
157- } else {
158-
159- if (CheckRuleAccepted(byPlayer) == false) {
160- //TODO: localize somehow?
161- byPlayer.SendMessage(GlobalConstants.CurrentChatGroup, "use '/rules' command for reading server rules.", EnumChatType.Notification);
162- }
163- }
164- }
165-
166-
167-
168100 private void PopulateAdminRoleTable( )
169101 {
170102 AdminRoles = new List<string>( );
@@ -181,43 +113,7 @@ namespace AdminToolkit
181113 }
182114 }
183115
184- private void PreloadRulesText( )
185- {
186- Rules = new Dictionary<string, List<string>>( );
187- RulesPath = ServerAPI.GetOrCreateDataPath(_rulesPathKey);
188-
189- string[] lang_codes = { "en", /*"fr", "es", "de", "ru", "kr" */};//FIXME: this should not be hardcoded
190-
191- foreach (var languageCode in lang_codes) {
192- //For each locale that is configured... get/create rules.txt
193- string nameRulesFile = string.Format("rules_{0}.txt", languageCode);
194- string rulesFilePath = Path.Combine(RulesPath, nameRulesFile);
195- if (File.Exists(rulesFilePath)) {
196- using (var ruleFileStream = File.OpenRead(rulesFilePath)) {
197- StreamReader ruleReader = new StreamReader(ruleFileStream);
198-
199- #if DEBUG
200- Mod.Logger.VerboseDebug($"found '{nameRulesFile}' of size {ruleFileStream.Length} bytes");
201- #endif
202-
203- string line;
204- while ((line = ruleReader.ReadLine()) != null)
205- {
206- if (Rules.ContainsKey(languageCode)) {
207- Rules[languageCode].Add(line);
208- } else {
209- Rules.Add(languageCode, new List<string>());
210- Rules[languageCode].Add(line);
211- }
212- }
213-
214- ruleReader.Close( );
215- }
216- } else {
217- Mod.Logger.Error("Non existant '{0}' file for Rules-text!!!",nameRulesFile);
218- }
219- }
220- }
116+
221117
222118 /// <summary>
223119 /// Makes Administrator text messages appear 'different'
@@ -237,7 +133,7 @@ namespace AdminToolkit
237133
238134 adminMessage.Append(letter);
239135 if (!Char.IsWhiteSpace(letter)) {
240- adminMessage.Append(@"̅̅̅");
136+ //adminMessage.Append(@"̅̅̅");
241137 adminMessage.Append(@"̲");
242138 }
243139 }
@@ -247,6 +143,20 @@ namespace AdminToolkit
247143 return message;
248144 }
249145
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+
250160 /// <summary>
251161 /// Say the formated text to a specific player / group / all
252162 /// </summary>
@@ -293,7 +203,7 @@ namespace AdminToolkit
293203 group_name = args.PopWord( );//More quotes?!
294204 message = args.PopAll( ); //Ugh - QUOTES?!
295205
296- //GET: PlayerGroupMembership
206+ //GET: PlayerGroupMembership list or number by name
297207
298208 //ServerAPI.SendMessageToGroup(0, message, EnumChatType.OthersMessage );
299209
@@ -316,16 +226,6 @@ namespace AdminToolkit
316226 }
317227 }
318228
319- private static bool CheckRuleAccepted(IServerPlayer byPlayer)
320- {
321- if (byPlayer.ServerData.CustomPlayerData.ContainsKey(_ruleAcceptKey)) {
322- bool ruleAccept;
323- if (bool.TryParse(byPlayer.ServerData.CustomPlayerData[_ruleAcceptKey], out ruleAccept)) {
324- return ruleAccept;
325- }
326- }
327- return false;
328- }
329229
330230
331231 }
--- /dev/null
+++ b/AdminToolkit/RulesCommand.cs
@@ -0,0 +1,229 @@
1+using System;
2+using System.Text;
3+using System.Linq;
4+using System.Collections.Generic;
5+using System.IO;
6+
7+
8+using Vintagestory.API.Common.Entities;
9+using Vintagestory.API.Server;
10+using Vintagestory.API.Common;
11+using Vintagestory.API.Config;
12+
13+namespace AdminToolkit
14+{
15+ public class RulesCommand : ServerChatCommand
16+ {
17+
18+ private const string _rulesPathKey = @"Rules";
19+ private const string _acceptKeyword = @"accept";
20+ private const string _ruleAcceptKey = @"RulesAccepted";
21+
22+ private string RulesPath;
23+ private Dictionary<string, List<string>> Rules;
24+
25+ private bool rolesAreValid;
26+
27+ private ICoreServerAPI ServerAPI;
28+ private ILogger Logger;
29+
30+ public RulesCommand(ICoreServerAPI _serverAPI)
31+ {
32+ ServerAPI = _serverAPI;
33+ Logger = ServerAPI.World.Logger;
34+
35+ PreloadRulesText( );
36+ ValidateAllRolesExist( );
37+
38+ this.Command = "rules";
39+ this.Description = "Display server Rules";
40+ this.handler += ServerRulesCommand;
41+
42+ this.ServerAPI.Event.PlayerJoin += UponJoin;
43+ }
44+
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+
56+ private void PreloadRulesText( )
57+ {
58+ Rules = new Dictionary<string, List<string>>( );
59+ RulesPath = ServerAPI.GetOrCreateDataPath(_rulesPathKey);
60+
61+ string[] lang_codes = { "en", /*"fr", "es", "de", "ru", "kr" */};//FIXME: this should not be hardcoded
62+
63+ foreach (var languageCode in lang_codes) {
64+ //For each locale that is configured... get/create rules.txt
65+ string rulesFilePath = Path.Combine(RulesPath, $"rules_{languageCode}.txt");
66+ if (File.Exists(rulesFilePath)) {
67+ using (var ruleFileStream = File.OpenRead(rulesFilePath)) {
68+ StreamReader ruleReader = new StreamReader(ruleFileStream);
69+
70+ #if DEBUG
71+ Logger.VerboseDebug($"found 'rules_{languageCode}.txt' of size {ruleFileStream.Length} bytes");
72+ #endif
73+
74+ string line;
75+ while ((line = ruleReader.ReadLine( )) != null) {
76+ if (Rules.ContainsKey(languageCode)) {
77+ Rules[languageCode].Add(line);
78+ } else {
79+ Rules.Add(languageCode, new List<string>( ));
80+ Rules[languageCode].Add(line);
81+ }
82+ }
83+
84+ ruleReader.Close( );
85+ }
86+ } else {
87+ Logger.Error("Non existant '{0}' file for Rules-text!!!", $"rules_{languageCode}.txt");
88+ }
89+ }
90+ }
91+
92+ private void ValidateAllRolesExist( )
93+ {
94+ if (!ServerAPI.Server.Config.Roles.Any(pr => pr.Code == this.CachedConfiguration.PlayerRoleNormal)) {
95+ Logger.Error("Role code defined for Normal missing: [{0}]", this.CachedConfiguration.PlayerRoleNormal);
96+
97+ } else if (!ServerAPI.Server.Config.Roles.Any(pr => pr.Code == this.CachedConfiguration.PlayerRoleRestrain)) {
98+ Logger.Error("Role code defined for Restrained missing: [{0}]", this.CachedConfiguration.PlayerRoleRestrain);
99+
100+ } else {
101+ Logger.VerboseDebug("Both role codes confgured are present.");
102+
103+ this.rolesAreValid = true;
104+ }
105+ }
106+
107+ internal static bool CheckRuleAccepted(IServerPlayer byPlayer)
108+ {
109+ if (byPlayer.ServerData.CustomPlayerData.ContainsKey(_ruleAcceptKey)) {
110+ bool ruleAccept;
111+ if (bool.TryParse(byPlayer.ServerData.CustomPlayerData[_ruleAcceptKey], out ruleAccept)) {
112+ return ruleAccept;
113+ }
114+ }
115+ return false;
116+ }
117+
118+ /// <summary>
119+ /// rules command
120+ /// </summary>
121+ /// <returns>The rules command.</returns>
122+ /// <param name="player">Player.</param>
123+ /// <param name="groupId">Group identifier.</param>
124+ /// <param name="args">Arguments.</param>
125+ private void ServerRulesCommand(IServerPlayer player, int groupId, CmdArgs args)
126+ {
127+ //Full printout of RULES file.
128+ //also Used for formally accepting the rules... should be logged - when accepting
129+
130+ if (args.Length == 1) {
131+ string word = args.PopWord( );
132+
133+ #if DEBUG
134+ if (string.Compare("demote", word, StringComparison.InvariantCultureIgnoreCase) == 0)
135+ {
136+ IPlayerRole restrainRole = ServerAPI.Server.Config.Roles.Single(rl => string.Compare(rl.Code, this.CachedConfiguration.PlayerRoleRestrain, StringComparison.InvariantCultureIgnoreCase) == 0);
137+ player.SendMessage(groupId, $"{player.PlayerName} was demoted", EnumChatType.CommandSuccess);
138+ ServerAPI.Permissions.SetRole(player, restrainRole.Code);
139+ }
140+
141+ if (string.Compare("promote", word, StringComparison.InvariantCultureIgnoreCase) == 0) {
142+ IPlayerRole normalRole = ServerAPI.Server.Config.Roles.Single(rl => string.Compare(rl.Code, this.CachedConfiguration.PlayerRoleNormal, StringComparison.InvariantCultureIgnoreCase) == 0);
143+ player.SendMessage(groupId, $"{player.PlayerName} was promoted", EnumChatType.CommandSuccess);
144+ ServerAPI.Permissions.SetRole(player, normalRole.Code);
145+ }
146+ #endif
147+
148+ if (string.Compare(_acceptKeyword, word, StringComparison.InvariantCultureIgnoreCase) == 0) {
149+
150+ if (CheckRuleAccepted(player) == false) {
151+ player.SendMessage(groupId, $"{player.PlayerName} YOU HAVE ACCEPTED RULES!", EnumChatType.CommandSuccess);
152+ player.ServerData.CustomPlayerData[_ruleAcceptKey] = true.ToString( );
153+ ServerAPI.Server.LogNotification($"Player:{player.PlayerName} UID: {player.PlayerUID} HAS ACCEPTED RULES @ {DateTime.Now.ToShortDateString( )}");
154+ PlayerAcceptsRulesAction( player);
155+ } else {
156+ player.SendMessage(groupId, $"{player.PlayerName} ALREADY ACCEPTED RULES!", EnumChatType.CommandSuccess);
157+ }
158+ } else {
159+ player.SendMessage(groupId, $"{player.PlayerName} type in chat console: /rules {_acceptKeyword}", EnumChatType.CommandError);
160+ }
161+
162+ } else {
163+ var targetLocale = "en";//TODO: actually get locale!
164+
165+ if (Rules.ContainsKey(targetLocale)) {
166+
167+ //TODO: rate limit for large files?
168+ foreach (var line in Rules[targetLocale]) {
169+ player.SendMessage(groupId, line, EnumChatType.OthersMessage);
170+ }
171+ } else {
172+ player.SendMessage(groupId, "* MISSING RULES FILE ! *", EnumChatType.CommandError);
173+ }
174+ }
175+ }
176+
177+ /// <summary>
178+ /// Send Rule info text or Admin welcome
179+ /// </summary>
180+ /// <param name="byPlayer">By player.</param>
181+ private void UponJoin(IServerPlayer byPlayer)
182+ {
183+ if (AdminToolkit.AdminRoles.Contains(byPlayer.Role.Code)) {
184+ //Annonce to all Admin\Moderator is here.
185+
186+ StringBuilder adminMessage = new StringBuilder( );
187+
188+ adminMessage.AppendFormat("<font color='{1}' weight='bold'>«{0}» ̠{2}̠ </font> Present.", byPlayer.Role.Name, byPlayer.Role.Color.Name, byPlayer.PlayerName);
189+
190+ ServerAPI.SendMessageToGroup(GlobalConstants.AllChatGroups, adminMessage.ToString( ), EnumChatType.AllGroups);
191+
192+ byPlayer.ServerData.CustomPlayerData[AdminToolkit._lastLoginKey] = DateTimeOffset.UtcNow.ToString("u");
193+
194+ } else {
195+
196+ if (RulesCommand.CheckRuleAccepted(byPlayer) == false) {
197+ //TODO: localize somehow?
198+ byPlayer.SendMessage(GlobalConstants.CurrentChatGroup, "use '/rules' command for reading server rules.", EnumChatType.Notification);
199+ PlayerNeverAcceptedRulesAction( byPlayer);
200+ }
201+ }
202+ }
203+
204+ private void PlayerAcceptsRulesAction(IServerPlayer byPlayer )
205+ {
206+ if (byPlayer.Role.Code == this.CachedConfiguration.PlayerRoleRestrain && this.rolesAreValid) {
207+ //Joined as 'restrained' player - will have their role changed to normal
208+
209+ IPlayerRole normalRole = ServerAPI.Server.Config.Roles.Single(rl => string.Compare(rl.Code, this.CachedConfiguration.PlayerRoleNormal, StringComparison.InvariantCultureIgnoreCase) == 0);
210+
211+ ServerAPI.Permissions.SetRole(byPlayer,normalRole.Code);
212+ Logger.Notification("Player {0} accepted the rules, and was promoted to role: {1}", byPlayer.PlayerName, byPlayer.Role.Name);
213+ }
214+ }
215+
216+ private void PlayerNeverAcceptedRulesAction(IServerPlayer byPlayer )
217+ {
218+ if (byPlayer.Role.Code == this.CachedConfiguration.PlayerRoleNormal && this.rolesAreValid) {
219+ //Joined as 'normal' player - will have their role changed to restricted
220+
221+ IPlayerRole restrainRole = ServerAPI.Server.Config.Roles.Single(rl => string.Compare( rl.Code, this.CachedConfiguration.PlayerRoleRestrain, StringComparison.InvariantCultureIgnoreCase) == 0);
222+
223+ ServerAPI.Permissions.SetRole(byPlayer, restrainRole.Code);
224+ Logger.Notification("Player {0} never accepted rules, and was demoted to role: {1}", byPlayer.PlayerName, byPlayer.Role.Name);
225+ }
226+ }
227+ }
228+}
229+
--- a/AdminToolkit/modinfo.json
+++ b/AdminToolkit/modinfo.json
@@ -5,7 +5,7 @@
55 "authors": ["Melchior", ],
66 "version": "0.1.0",
77 "dependencies": {
8- "game": "1.9.11"
8+ "game": "1.10.*"
99 },
1010 "website": "http://nowebsite.nope"
1111 }