]> git.lizzy.rs Git - minetest-m13.git/blob - src/servercommand.cpp
e2e84bacb000945e4bf2ac08a392217cc8045fea
[minetest-m13.git] / src / servercommand.cpp
1 /*
2 Part of Minetest-c55
3 Copyright (C) 2010-11 celeron55, Perttu Ahola <celeron55@gmail.com>
4 Copyright (C) 2011 Ciaran Gultnieks <ciaran@ciarang.com>
5
6 Permission to use, copy, modify, and distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include "servercommand.h"
20 #include "utility.h"
21 #include "settings.h"
22 #include "main.h" // For g_settings
23
24 #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
25
26 void cmd_status(std::wostringstream &os,
27         ServerCommandContext *ctx)
28 {
29         os<<ctx->server->getStatusString();
30 }
31
32 void cmd_me(std::wostringstream &os,
33         ServerCommandContext *ctx)
34 {
35         std::wstring name = narrow_to_wide(ctx->player->getName());
36         os << L"* " << name << L" " << ctx->paramstring;
37         ctx->flags |= SEND_TO_OTHERS | SEND_NO_PREFIX;
38 }
39
40 void cmd_privs(std::wostringstream &os,
41         ServerCommandContext *ctx)
42 {
43         if(ctx->parms.size() == 1)
44         {
45                 // Show our own real privs, without any adjustments
46                 // made for admin status
47                 os<<L"-!- " + narrow_to_wide(privsToString(
48                                 ctx->server->getPlayerAuthPrivs(ctx->player->getName())));
49                 return;
50         }
51
52         if((ctx->privs & PRIV_PRIVS) == 0)
53         {
54                 os<<L"-!- You don't have permission to do that";
55                 return;
56         }
57                 
58         Player *tp = ctx->env->getPlayer(wide_to_narrow(ctx->parms[1]).c_str());
59         if(tp == NULL)
60         {
61                 os<<L"-!- No such player";
62                 return;
63         }
64         
65         os<<L"-!- " + narrow_to_wide(privsToString(ctx->server->getPlayerAuthPrivs(tp->getName())));
66 }
67
68 void cmd_grantrevoke(std::wostringstream &os,
69         ServerCommandContext *ctx)
70 {
71         if(ctx->parms.size() != 3)
72         {
73                 os<<L"-!- Missing parameter";
74                 return;
75         }
76
77         if((ctx->privs & PRIV_PRIVS) == 0)
78         {
79                 os<<L"-!- You don't have permission to do that";
80                 return;
81         }
82
83         u64 newprivs = stringToPrivs(wide_to_narrow(ctx->parms[2]));
84         if(newprivs == PRIV_INVALID)
85         {
86                 os<<L"-!- Invalid privileges specified";
87                 return;
88         }
89
90         Player *tp = ctx->env->getPlayer(wide_to_narrow(ctx->parms[1]).c_str());
91         if(tp == NULL)
92         {
93                 os<<L"-!- No such player";
94                 return;
95         }
96         
97         std::string playername = wide_to_narrow(ctx->parms[1]);
98         u64 privs = ctx->server->getPlayerAuthPrivs(playername);
99
100         if(ctx->parms[0] == L"grant"){
101                 privs |= newprivs;
102                 actionstream<<ctx->player->getName()<<" grants "
103                                 <<wide_to_narrow(ctx->parms[2])<<" to "
104                                 <<playername<<std::endl;
105
106                 std::wstring msg;
107                 msg += narrow_to_wide(ctx->player->getName());
108                 msg += L" granted you the privilege \"";
109                 msg += ctx->parms[2];
110                 msg += L"\"";
111                 ctx->server->notifyPlayer(playername.c_str(), msg);
112         } else {
113                 privs &= ~newprivs;
114                 actionstream<<ctx->player->getName()<<" revokes "
115                                 <<wide_to_narrow(ctx->parms[2])<<" from "
116                                 <<playername<<std::endl;
117
118                 std::wstring msg;
119                 msg += narrow_to_wide(ctx->player->getName());
120                 msg += L" revoked from you the privilege \"";
121                 msg += ctx->parms[2];
122                 msg += L"\"";
123                 ctx->server->notifyPlayer(playername.c_str(), msg);
124         }
125         
126         ctx->server->setPlayerAuthPrivs(playername, privs);
127         
128         os<<L"-!- Privileges change to ";
129         os<<narrow_to_wide(privsToString(privs));
130 }
131
132 void cmd_time(std::wostringstream &os,
133         ServerCommandContext *ctx)
134 {
135         if(ctx->parms.size() != 2)
136         {
137                 os<<L"-!- Missing parameter";
138                 return;
139         }
140
141         if((ctx->privs & PRIV_SETTIME) ==0)
142         {
143                 os<<L"-!- You don't have permission to do that";
144                 return;
145         }
146
147         u32 time = stoi(wide_to_narrow(ctx->parms[1]));
148         ctx->server->setTimeOfDay(time);
149         os<<L"-!- time_of_day changed.";
150
151         actionstream<<ctx->player->getName()<<" sets time "
152                         <<time<<std::endl;
153 }
154
155 void cmd_shutdown(std::wostringstream &os,
156         ServerCommandContext *ctx)
157 {
158         if((ctx->privs & PRIV_SERVER) ==0)
159         {
160                 os<<L"-!- You don't have permission to do that";
161                 return;
162         }
163
164         actionstream<<ctx->player->getName()
165                         <<" shuts down server"<<std::endl;
166
167         ctx->server->requestShutdown();
168                                         
169         os<<L"*** Server shutting down (operator request)";
170         ctx->flags |= SEND_TO_OTHERS;
171 }
172
173 void cmd_setting(std::wostringstream &os,
174         ServerCommandContext *ctx)
175 {
176         if((ctx->privs & PRIV_SERVER) ==0)
177         {
178                 os<<L"-!- You don't have permission to do that";
179                 return;
180         }
181
182         /*std::string confline = wide_to_narrow(
183                         ctx->parms[1] + L" = " + ctx->params[2]);*/
184
185         std::string confline = wide_to_narrow(ctx->paramstring);
186         
187         actionstream<<ctx->player->getName()
188                         <<" sets: "<<confline<<std::endl;
189
190         g_settings->parseConfigLine(confline);
191         
192         ctx->server->saveConfig();
193
194         os<< L"-!- Setting changed and configuration saved.";
195 }
196
197 void cmd_teleport(std::wostringstream &os,
198         ServerCommandContext *ctx)
199 {
200         if((ctx->privs & PRIV_TELEPORT) ==0)
201         {
202                 os<<L"-!- You don't have permission to do that";
203                 return;
204         }
205
206         if(ctx->parms.size() != 2)
207         {
208                 os<<L"-!- Missing parameter";
209                 return;
210         }
211
212         std::vector<std::wstring> coords = str_split(ctx->parms[1], L',');
213         if(coords.size() != 3)
214         {
215                 os<<L"-!- You can only specify coordinates currently";
216                 return;
217         }
218
219         v3f dest(stoi(coords[0])*10, stoi(coords[1])*10, stoi(coords[2])*10);
220
221         actionstream<<ctx->player->getName()<<" teleports from "
222                         <<PP(ctx->player->getPosition()/BS)<<" to "
223                         <<PP(dest/BS)<<std::endl;
224
225         //ctx->player->setPosition(dest);
226
227         // Use the ServerActiveObject interface of ServerRemotePlayer
228         ServerRemotePlayer *srp = static_cast<ServerRemotePlayer*>(ctx->player);
229         srp->setPos(dest);
230         ctx->server->SendMovePlayer(ctx->player);
231
232         os<< L"-!- Teleported.";
233 }
234
235 void cmd_banunban(std::wostringstream &os, ServerCommandContext *ctx)
236 {
237         if((ctx->privs & PRIV_BAN) == 0)
238         {
239                 os<<L"-!- You don't have permission to do that";
240                 return;
241         }
242
243         if(ctx->parms.size() < 2)
244         {
245                 std::string desc = ctx->server->getBanDescription("");
246                 os<<L"-!- Ban list: "<<narrow_to_wide(desc);
247                 return;
248         }
249         if(ctx->parms[0] == L"ban")
250         {
251                 Player *player = ctx->env->getPlayer(wide_to_narrow(ctx->parms[1]).c_str());
252
253                 if(player == NULL)
254                 {
255                         os<<L"-!- No such player";
256                         return;
257                 }
258                 
259                 try{
260                         Address address = ctx->server->getPeerAddress(player->peer_id);
261                         std::string ip_string = address.serializeString();
262                         ctx->server->setIpBanned(ip_string, player->getName());
263                         os<<L"-!- Banned "<<narrow_to_wide(ip_string)<<L"|"
264                                         <<narrow_to_wide(player->getName());
265
266                         actionstream<<ctx->player->getName()<<" bans "
267                                         <<player->getName()<<" / "<<ip_string<<std::endl;
268                 } catch(con::PeerNotFoundException){
269                         dstream<<__FUNCTION_NAME<<": peer was not found"<<std::endl;
270                 }
271         }
272         else
273         {
274                 std::string ip_or_name = wide_to_narrow(ctx->parms[1]);
275                 std::string desc = ctx->server->getBanDescription(ip_or_name);
276                 ctx->server->unsetIpBanned(ip_or_name);
277                 os<<L"-!- Unbanned "<<narrow_to_wide(desc);
278
279                 actionstream<<ctx->player->getName()<<" unbans "
280                                 <<ip_or_name<<std::endl;
281         }
282 }
283
284 void cmd_setclearpassword(std::wostringstream &os,
285         ServerCommandContext *ctx)
286 {
287         if((ctx->privs & PRIV_PASSWORD) == 0)
288         {
289                 os<<L"-!- You don't have permission to do that";
290                 return;
291         }
292
293         std::string playername;
294         std::wstring password;
295
296         if(ctx->parms[0] == L"setpassword")
297         {
298                 if(ctx->parms.size() != 3)
299                 {
300                         os<<L"-!- Missing parameter";
301                         return;
302                 }
303
304                 playername = wide_to_narrow(ctx->parms[1]);
305                 password = ctx->parms[2];
306
307                 actionstream<<ctx->player->getName()<<" sets password of "
308                         <<playername<<std::endl;
309         }
310         else
311         {
312                 // clearpassword
313
314                 if(ctx->parms.size() != 2)
315                 {
316                         os<<L"-!- Missing parameter";
317                         return;
318                 }
319
320                 playername = wide_to_narrow(ctx->parms[1]);
321                 password = L"";
322
323                 actionstream<<ctx->player->getName()<<" clears password of"
324                         <<playername<<std::endl;
325         }
326
327         ctx->server->setPlayerPassword(playername, password);
328
329         std::wostringstream msg;
330         msg<<ctx->player->getName()<<L" changed your password";
331         ctx->server->notifyPlayer(playername.c_str(), msg.str());
332
333         os<<L"-!- Password change for "<<narrow_to_wide(playername)<<" successful";
334 }
335
336 void cmd_clearobjects(std::wostringstream &os,
337         ServerCommandContext *ctx)
338 {
339         if((ctx->privs & PRIV_SERVER) ==0)
340         {
341                 os<<L"-!- You don't have permission to do that";
342                 return;
343         }
344
345         actionstream<<ctx->player->getName()
346                         <<" clears all objects"<<std::endl;
347         
348         {
349                 std::wstring msg;
350                 msg += L"Clearing all objects. This may take long.";
351                 msg += L" You may experience a timeout. (by ";
352                 msg += narrow_to_wide(ctx->player->getName());
353                 msg += L")";
354                 ctx->server->notifyPlayers(msg);
355         }
356
357         ctx->env->clearAllObjects();
358                                         
359         actionstream<<"object clearing done"<<std::endl;
360         
361         os<<L"*** cleared all objects";
362         ctx->flags |= SEND_TO_OTHERS;
363 }
364
365
366 std::wstring processServerCommand(ServerCommandContext *ctx)
367 {
368
369         std::wostringstream os(std::ios_base::binary);
370         ctx->flags = SEND_TO_SENDER;    // Default, unless we change it.
371
372         u64 privs = ctx->privs;
373
374         if(ctx->parms.size() == 0 || ctx->parms[0] == L"help")
375         {
376                 os<<L"-!- Available commands: ";
377                 os<<L"me status privs";
378                 if(privs & PRIV_SERVER)
379                         os<<L" shutdown setting clearobjects";
380                 if(privs & PRIV_SETTIME)
381                         os<<L" time";
382                 if(privs & PRIV_TELEPORT)
383                         os<<L" teleport";
384                 if(privs & PRIV_PRIVS)
385                         os<<L" grant revoke";
386                 if(privs & PRIV_BAN)
387                         os<<L" ban unban";
388                 if(privs & PRIV_PASSWORD)
389                         os<<L" setpassword clearpassword";
390         }
391         else if(ctx->parms[0] == L"status")
392                 cmd_status(os, ctx);
393         else if(ctx->parms[0] == L"privs")
394                 cmd_privs(os, ctx);
395         else if(ctx->parms[0] == L"grant" || ctx->parms[0] == L"revoke")
396                 cmd_grantrevoke(os, ctx);
397         else if(ctx->parms[0] == L"time")
398                 cmd_time(os, ctx);
399         else if(ctx->parms[0] == L"shutdown")
400                 cmd_shutdown(os, ctx);
401         else if(ctx->parms[0] == L"setting")
402                 cmd_setting(os, ctx);
403         else if(ctx->parms[0] == L"teleport")
404                 cmd_teleport(os, ctx);
405         else if(ctx->parms[0] == L"ban" || ctx->parms[0] == L"unban")
406                 cmd_banunban(os, ctx);
407         else if(ctx->parms[0] == L"setpassword" || ctx->parms[0] == L"clearpassword")
408                 cmd_setclearpassword(os, ctx);
409         else if(ctx->parms[0] == L"me")
410                 cmd_me(os, ctx);
411         else if(ctx->parms[0] == L"clearobjects")
412                 cmd_clearobjects(os, ctx);
413         else
414                 os<<L"-!- Invalid command: " + ctx->parms[0];
415         
416         return os.str();
417 }
418
419