Administrator's Toolkit VS plugin
修订版 | 8ba00983036921e9c1b2e200b15862006546750a (tree) |
---|---|
时间 | 2020-09-14 05:08:34 |
作者 | melchior <melchior@user...> |
Commiter | melchior |
W.I.P. Untested sp fix
@@ -16,7 +16,7 @@ using ProtoBuf; | ||
16 | 16 | namespace AdminToolkit |
17 | 17 | { |
18 | 18 | [ProtoContract] |
19 | - public struct Spawnpoint | |
19 | + internal struct Spawnpoint | |
20 | 20 | { |
21 | 21 | [ProtoMember(1)] |
22 | 22 | public PlayerSpawnPos Location; |
@@ -49,52 +49,23 @@ namespace AdminToolkit | ||
49 | 49 | this.Command = "spawnpoints"; |
50 | 50 | this.Description = "Control add/remove/adjust List of approved player spawn points"; |
51 | 51 | this.RequiredPrivilege = Privilege.setspawn; |
52 | - this.Syntax = @"Add {name} {123,456,-678}|here / Remove {name} / List / Enable / Disable"; | |
52 | + this.Syntax = @"Add {name} {123 456 -678}|here / Remove {name} / List / Enable / Disable"; | |
53 | 53 | this.handler += HandleCommand; |
54 | 54 | |
55 | 55 | ServerAPI.Event.ServerRunPhase(EnumServerRunPhase.RunGame, ReloadSpawnpoints); |
56 | - ServerAPI.Event.PlayerCreate += NewPlayerCreation; | |
56 | + ServerAPI.Event.PlayerJoin += PlayerJoins; | |
57 | 57 | ServerAPI.Event.PlayerDeath += PlayerDied; |
58 | 58 | ServerAPI.Event.ServerRunPhase(EnumServerRunPhase.Shutdown, PersistSpawnpoints); |
59 | 59 | } |
60 | 60 | |
61 | - private void ReloadSpawnpoints( ) | |
62 | - { | |
63 | - var spawnsBytes = ServerAPI.WorldManager.SaveGame.GetData(_spawnsDataKey); | |
64 | - | |
65 | - if (spawnsBytes != null) { | |
66 | - this.Spawnpoints = SerializerUtil.Deserialize<List<Spawnpoint>>(spawnsBytes); | |
67 | - Logger.Notification("Loaded Variable-Spawns # ({0})", Spawnpoints.Count); | |
68 | - } | |
69 | - else { | |
70 | - this.Spawnpoints = new List<Spawnpoint>( ); | |
71 | - | |
72 | - var emptySpawnsList = SerializerUtil.Serialize(this.Spawnpoints); | |
73 | - | |
74 | - ServerAPI.WorldManager.SaveGame.StoreData(_spawnsDataKey, emptySpawnsList); | |
75 | - | |
76 | - Logger.Notification("Created (empty) Spawnpoints Data"); | |
77 | - } | |
78 | - | |
79 | - | |
80 | - } | |
81 | - | |
82 | - private void PersistSpawnpoints( ) | |
83 | - { | |
84 | - if (this.Spawnpoints != null && this.Spawnpoints.Count > 0) { | |
85 | - var spawnDatas = SerializerUtil.Serialize(this.Spawnpoints); | |
86 | - ServerAPI.WorldManager.SaveGame.StoreData(_spawnsDataKey, spawnDatas); | |
87 | - Logger.Notification("Persisted Spawnpoints Data"); | |
88 | - } | |
89 | 61 | |
90 | - } | |
91 | 62 | |
92 | 63 | private void HandleCommand(IServerPlayer player, int groupId, CmdArgs args) |
93 | 64 | { |
94 | 65 | string name; |
95 | 66 | Vec3i position; |
96 | - | |
97 | - | |
67 | + | |
68 | + bool console = player is ServerConsolePlayer; | |
98 | 69 | |
99 | 70 | if (args.Length >= 1) { |
100 | 71 | string cmd = args.PopWord(string.Empty).ToLowerInvariant(); |
@@ -103,19 +74,26 @@ namespace AdminToolkit | ||
103 | 74 | case "add": |
104 | 75 | name = args.PopWord("?"); |
105 | 76 | |
106 | - if (String.Equals(args.PeekWord(), "here", StringComparison.OrdinalIgnoreCase)) { | |
77 | + if (console == false && String.Equals(args.PeekWord( ), "here", StringComparison.OrdinalIgnoreCase)) { | |
107 | 78 | position = player.Entity.Pos.XYZInt; |
108 | 79 | } |
109 | - position = args.PopVec3i(player.Entity.Pos.XYZInt); | |
80 | + else { | |
81 | + var pos = args.PopVec3i(ServerAPI.World.DefaultSpawnPosition.AsBlockPos.ToVec3i( )); | |
82 | + position = RelativeToAbsolute(pos); | |
83 | + } | |
84 | + | |
110 | 85 | if (AddSpawnpoint(name, position)) { |
111 | - player.SendMessage(groupId, "Added Spawnpoint", EnumChatType.CommandSuccess); | |
86 | + player.SendMessage(groupId, "Added Spawnpoint.", EnumChatType.CommandSuccess); | |
87 | + } | |
88 | + else { | |
89 | + player.SendMessage(groupId, "Can't add Spawnpoint!", EnumChatType.CommandError); | |
112 | 90 | } |
113 | 91 | break; |
114 | 92 | |
115 | 93 | case "remove": |
116 | 94 | name = args.PopWord( ); |
117 | 95 | if (RemoveSpawnpoint(name)) { |
118 | - player.SendMessage(groupId, "Removed Spawnpoint", EnumChatType.CommandSuccess); | |
96 | + player.SendMessage(groupId, $"Removed Spawnpoint '{name}'", EnumChatType.CommandSuccess); | |
119 | 97 | } |
120 | 98 | break; |
121 | 99 |
@@ -131,6 +109,16 @@ namespace AdminToolkit | ||
131 | 109 | Toggle(false); |
132 | 110 | break; |
133 | 111 | |
112 | + case "reset": | |
113 | + if (console) { | |
114 | + name = args.PopWord("?"); | |
115 | + #if DEBUG | |
116 | + ResetPlayer(name); | |
117 | + player.SendMessage(groupId, $"Reset Playerdata for '{name}'", EnumChatType.CommandSuccess); | |
118 | + #endif | |
119 | + } | |
120 | + break; | |
121 | + | |
134 | 122 | default: |
135 | 123 | player.SendMessage(groupId, "Unrecognised command ", EnumChatType.CommandError); |
136 | 124 | break; |
@@ -161,7 +149,7 @@ namespace AdminToolkit | ||
161 | 149 | return true; |
162 | 150 | } |
163 | 151 | else { |
164 | - Logger.VerboseDebug($"Apparently spawnpoint Unsafe! @ {position}"); | |
152 | + Logger.VerboseDebug($"Apparently '{name}' spawnpoint is Unsafe! @ABS:{position}"); | |
165 | 153 | } |
166 | 154 | |
167 | 155 | return false; |
@@ -182,7 +170,7 @@ namespace AdminToolkit | ||
182 | 170 | { |
183 | 171 | if (this.Spawnpoints.Count > 0) { |
184 | 172 | foreach (var sp in this.Spawnpoints) { |
185 | - player.SendMessage(chatGroupId, $"Spawn: '{sp.Name}' @({sp.Location})", EnumChatType.CommandSuccess); | |
173 | + player.SendMessage(chatGroupId, $"Spawn: '{sp.Name}' ({PrettyFormat(sp.Location)}) ABS:({sp.Location})", EnumChatType.CommandSuccess); | |
186 | 174 | } |
187 | 175 | } |
188 | 176 | } |
@@ -192,18 +180,62 @@ namespace AdminToolkit | ||
192 | 180 | this.CachedConfiguration.VariableSpawnpoints = state; |
193 | 181 | } |
194 | 182 | |
195 | - private void NewPlayerCreation( IServerPlayer byPlayer) | |
183 | + private void ResetPlayer(string name) | |
184 | + { | |
185 | + var byPlayer = ServerAPI.Server.Players.SingleOrDefault(plr => plr.PlayerName == name); | |
186 | + if (byPlayer != null && this.Spawnpoints != null && this.Spawnpoints.Count > 0) | |
187 | + { | |
188 | + byPlayer.ClearSpawnPosition( ); | |
189 | + //var datas = ServerAPI.PlayerData.GetPlayerDataByUid(byPlayer.PlayerUID); | |
190 | + //datas. | |
191 | + //ServerAPI.Server.Players.Remove(byPlayer); //List is a array copy | |
192 | + var servPlayer = byPlayer as ServerPlayer; | |
193 | + | |
194 | + } | |
195 | + } | |
196 | + | |
197 | + #region Events | |
198 | + | |
199 | + private void ReloadSpawnpoints( ) | |
200 | + { | |
201 | + var spawnsBytes = ServerAPI.WorldManager.SaveGame.GetData(_spawnsDataKey); | |
202 | + | |
203 | + if (spawnsBytes != null) { | |
204 | + this.Spawnpoints = SerializerUtil.Deserialize<List<Spawnpoint>>(spawnsBytes); | |
205 | + Logger.Notification("Loaded Variable-Spawns # ({0}) STATE: {1}", Spawnpoints.Count, (this.CachedConfiguration.VariableSpawnpoints ? "Enabled" : "Disabled")); | |
206 | + } | |
207 | + else { | |
208 | + this.Spawnpoints = new List<Spawnpoint>( ); | |
209 | + | |
210 | + var emptySpawnsList = SerializerUtil.Serialize(this.Spawnpoints); | |
211 | + | |
212 | + ServerAPI.WorldManager.SaveGame.StoreData(_spawnsDataKey, emptySpawnsList); | |
213 | + | |
214 | + Logger.Notification("Created (empty) Spawnpoints Data"); | |
215 | + } | |
216 | + | |
217 | + | |
218 | + } | |
219 | + | |
220 | + private void PersistSpawnpoints( ) | |
221 | + { | |
222 | + if (this.Spawnpoints != null && this.Spawnpoints.Count > 0) { | |
223 | + var spawnDatas = SerializerUtil.Serialize(this.Spawnpoints); | |
224 | + ServerAPI.WorldManager.SaveGame.StoreData(_spawnsDataKey, spawnDatas); | |
225 | + Logger.Notification("Persisted Spawnpoints Data"); | |
226 | + } | |
227 | + | |
228 | + } | |
229 | + | |
230 | + private void PlayerJoins( IServerPlayer byPlayer) | |
196 | 231 | { |
197 | 232 | if (this.CachedConfiguration.VariableSpawnpoints && this.Spawnpoints.Count > 0) { |
198 | 233 | |
199 | 234 | var swpd = byPlayer.WorldData as ServerWorldPlayerData; |
200 | - if (swpd.SpawnPosition == null) { | |
201 | - var newSP = RandomSpawnpoint( ); | |
202 | - byPlayer.SetSpawnPosition(newSP.Location); | |
203 | - #if DEBUG | |
204 | - Logger.VerboseDebug($"New spawn Pos: '{newSP.Name}' @ {newSP.Location} "); | |
205 | - #endif | |
206 | - } | |
235 | + if (swpd.SpawnPosition == null || KnownSpawn(swpd.SpawnPosition)) | |
236 | + { | |
237 | + RandomizeSpawnpoint(byPlayer); | |
238 | + } | |
207 | 239 | } |
208 | 240 | } |
209 | 241 |
@@ -212,19 +244,23 @@ namespace AdminToolkit | ||
212 | 244 | if (this.CachedConfiguration.VariableSpawnpoints && this.Spawnpoints.Count > 0) { |
213 | 245 | |
214 | 246 | var swpd = byPlayer.WorldData as ServerWorldPlayerData; |
215 | - if (swpd.SpawnPosition == null || KnownSpawn(swpd.SpawnPosition)) { | |
216 | - var newSP = RandomSpawnpoint( ); | |
217 | - byPlayer.SetSpawnPosition(newSP.Location); | |
218 | - #if DEBUG | |
219 | - Logger.VerboseDebug( $"Changed spawn Pos: '{newSP.Name}' @ {newSP.Location} "); | |
220 | - #endif | |
221 | - } | |
247 | + if (swpd.SpawnPosition == null || KnownSpawn(swpd.SpawnPosition)) | |
248 | + { | |
249 | + RandomizeSpawnpoint(byPlayer); | |
250 | + } | |
222 | 251 | } |
223 | 252 | } |
224 | 253 | |
225 | - private Spawnpoint RandomSpawnpoint( ) | |
254 | + #endregion | |
255 | + | |
256 | + | |
257 | + private void RandomizeSpawnpoint(IServerPlayer byPlayer) | |
226 | 258 | { |
227 | - return this.Spawnpoints[random.Next(0, Spawnpoints.Count - 1)]; | |
259 | + var randSp = this.Spawnpoints[random.Next(0, Spawnpoints.Count - 1)]; | |
260 | + byPlayer.SetSpawnPosition(randSp.Location); | |
261 | + #if DEBUG | |
262 | + Logger.VerboseDebug($"Changed spawn Pos: '{randSp.Name}' @ {randSp.Location} for {byPlayer.PlayerName}"); | |
263 | + #endif | |
228 | 264 | } |
229 | 265 | |
230 | 266 | private bool KnownSpawn(PlayerSpawnPos aSpawn) |
@@ -237,6 +273,32 @@ namespace AdminToolkit | ||
237 | 273 | |
238 | 274 | return false; |
239 | 275 | } |
276 | + | |
277 | + private Vec3i RelativeToAbsolute(Vec3i location) | |
278 | + { | |
279 | + var start = ServerAPI.World.DefaultSpawnPosition.AsBlockPos; | |
280 | + return new Vec3i( location.X + start.X, location.Y, location.Z + start.Z); | |
281 | + } | |
282 | + | |
283 | + private Vec3i AbsoluteToRelative(Vec3i location) | |
284 | + { | |
285 | + var start = ServerAPI.World.DefaultSpawnPosition.AsBlockPos; | |
286 | + return new Vec3i(start.X - location.X, location.Y, start.Z - location.Z); | |
287 | + } | |
288 | + | |
289 | + private string PrettyFormat(PlayerSpawnPos spawnPos) | |
290 | + { | |
291 | + var start = ServerAPI.World.DefaultSpawnPosition.AsBlockPos; | |
292 | + | |
293 | + return String.Format | |
294 | + ( | |
295 | + @"{0:D}, {1:D}, {2:D}", | |
296 | + spawnPos.x - start.X, | |
297 | + spawnPos.y - start.Y, | |
298 | + spawnPos.z - start.Z | |
299 | + ); | |
300 | + | |
301 | + } | |
240 | 302 | } |
241 | 303 | } |
242 | 304 |
@@ -1,5 +1,5 @@ | ||
1 | 1 | |
2 | -Instructions for using the Administrator's Toolkit (V0.3.3); | |
2 | +Instructions for using the Administrator's Toolkit (V0.3.6); | |
3 | 3 | ============================================================ |
4 | 4 | |
5 | 5 | It provides the (server side only) commands: |
@@ -7,6 +7,12 @@ It provides the (server side only) commands: | ||
7 | 7 | * /rules |
8 | 8 | * /admins |
9 | 9 | * /backups |
10 | +* /pings | |
11 | +* /spawnpoints | |
12 | + | |
13 | +The configuration file: 'admintoolkit.json' ( %home%/.config/VintagestoryData/ModConfig ); | |
14 | +Note: by default most features are _DISABLED_ . | |
15 | + | |
10 | 16 | |
11 | 17 | RULES |
12 | 18 | ----- |
@@ -97,3 +103,30 @@ A special feature for admins; their text messages get underlined. | ||
97 | 103 | edit file ('/ModConfig/admintoolkit.json' ) : |
98 | 104 | |
99 | 105 | > "BoomingVoice": true |
106 | + | |
107 | + | |
108 | + | |
109 | +VAIRABLE SPAWNS | |
110 | +--------------- | |
111 | + | |
112 | +Lets admins define and have players spawn from a list of pre-defined coordinates. | |
113 | +(chosen at random) | |
114 | + | |
115 | +Config file setting: "VariableSpawnpoints" : set value to 'true' or 'false' (no quotes) | |
116 | + | |
117 | +Use command: | |
118 | +/spawnpoints | |
119 | + | |
120 | +/spawnpoints add {name} {5123 100 3992} | here | |
121 | + | |
122 | +(either 'here' where admin is standing OR manually entered RELATIVE (to-spawn) coordinates) | |
123 | + | |
124 | +/spawnpoints remove {name} | |
125 | + | |
126 | +(by name of spawnpoint) | |
127 | + | |
128 | +/spawnpoints list | |
129 | + | |
130 | +/spawnpoints enable | |
131 | + | |
132 | +/spawnpoints disable |