]> git.lizzy.rs Git - minetest.git/blob - src/servercommand.cpp
3c6868e36d8392818e09999b477ced1b15676fc5
[minetest.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         ctx->server->SendMovePlayer(ctx->player);
227
228         os<< L"-!- Teleported.";
229 }
230
231 void cmd_banunban(std::wostringstream &os, ServerCommandContext *ctx)
232 {
233         if((ctx->privs & PRIV_BAN) == 0)
234         {
235                 os<<L"-!- You don't have permission to do that";
236                 return;
237         }
238
239         if(ctx->parms.size() < 2)
240         {
241                 std::string desc = ctx->server->getBanDescription("");
242                 os<<L"-!- Ban list: "<<narrow_to_wide(desc);
243                 return;
244         }
245         if(ctx->parms[0] == L"ban")
246         {
247                 Player *player = ctx->env->getPlayer(wide_to_narrow(ctx->parms[1]).c_str());
248
249                 if(player == NULL)
250                 {
251                         os<<L"-!- No such player";
252                         return;
253                 }
254                 
255                 try{
256                         Address address = ctx->server->getPeerAddress(player->peer_id);
257                         std::string ip_string = address.serializeString();
258                         ctx->server->setIpBanned(ip_string, player->getName());
259                         os<<L"-!- Banned "<<narrow_to_wide(ip_string)<<L"|"
260                                         <<narrow_to_wide(player->getName());
261
262                         actionstream<<ctx->player->getName()<<" bans "
263                                         <<player->getName()<<" / "<<ip_string<<std::endl;
264                 } catch(con::PeerNotFoundException){
265                         dstream<<__FUNCTION_NAME<<": peer was not found"<<std::endl;
266                 }
267         }
268         else
269         {
270                 std::string ip_or_name = wide_to_narrow(ctx->parms[1]);
271                 std::string desc = ctx->server->getBanDescription(ip_or_name);
272                 ctx->server->unsetIpBanned(ip_or_name);
273                 os<<L"-!- Unbanned "<<narrow_to_wide(desc);
274
275                 actionstream<<ctx->player->getName()<<" unbans "
276                                 <<ip_or_name<<std::endl;
277         }
278 }
279
280 void cmd_clearobjects(std::wostringstream &os,
281         ServerCommandContext *ctx)
282 {
283         if((ctx->privs & PRIV_SERVER) ==0)
284         {
285                 os<<L"-!- You don't have permission to do that";
286                 return;
287         }
288
289         actionstream<<ctx->player->getName()
290                         <<" clears all objects"<<std::endl;
291         
292         {
293                 std::wstring msg;
294                 msg += L"Clearing all objects. This may take long.";
295                 msg += L" You may experience a timeout. (by ";
296                 msg += narrow_to_wide(ctx->player->getName());
297                 msg += L")";
298                 ctx->server->notifyPlayers(msg);
299         }
300
301         ctx->env->clearAllObjects();
302                                         
303         actionstream<<"object clearing done"<<std::endl;
304         
305         os<<L"*** cleared all objects";
306         ctx->flags |= SEND_TO_OTHERS;
307 }
308
309
310 std::wstring processServerCommand(ServerCommandContext *ctx)
311 {
312
313         std::wostringstream os(std::ios_base::binary);
314         ctx->flags = SEND_TO_SENDER;    // Default, unless we change it.
315
316         u64 privs = ctx->privs;
317
318         if(ctx->parms.size() == 0 || ctx->parms[0] == L"help")
319         {
320                 os<<L"-!- Available commands: ";
321                 os<<L"status privs ";
322                 if(privs & PRIV_SERVER)
323                         os<<L"shutdown setting ";
324                 if(privs & PRIV_SETTIME)
325                         os<<L" time";
326                 if(privs & PRIV_TELEPORT)
327                         os<<L" teleport";
328                 if(privs & PRIV_PRIVS)
329                         os<<L" grant revoke";
330                 if(privs & PRIV_BAN)
331                         os<<L" ban unban";
332         }
333         else if(ctx->parms[0] == L"status")
334                 cmd_status(os, ctx);
335         else if(ctx->parms[0] == L"privs")
336                 cmd_privs(os, ctx);
337         else if(ctx->parms[0] == L"grant" || ctx->parms[0] == L"revoke")
338                 cmd_grantrevoke(os, ctx);
339         else if(ctx->parms[0] == L"time")
340                 cmd_time(os, ctx);
341         else if(ctx->parms[0] == L"shutdown")
342                 cmd_shutdown(os, ctx);
343         else if(ctx->parms[0] == L"setting")
344                 cmd_setting(os, ctx);
345         else if(ctx->parms[0] == L"teleport")
346                 cmd_teleport(os, ctx);
347         else if(ctx->parms[0] == L"ban" || ctx->parms[0] == L"unban")
348                 cmd_banunban(os, ctx);
349         else if(ctx->parms[0] == L"me")
350                 cmd_me(os, ctx);
351         else if(ctx->parms[0] == L"clearobjects")
352                 cmd_clearobjects(os, ctx);
353         else
354                 os<<L"-!- Invalid command: " + ctx->parms[0];
355         
356         return os.str();
357 }
358
359