]> git.lizzy.rs Git - minetest.git/blob - src/servercommand.cpp
When granting or revoking privileges, notify the target player too
[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
23 #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
24
25 void cmd_status(std::wostringstream &os,
26         ServerCommandContext *ctx)
27 {
28         os<<ctx->server->getStatusString();
29 }
30
31 void cmd_me(std::wostringstream &os,
32         ServerCommandContext *ctx)
33 {
34         std::wstring name = narrow_to_wide(ctx->player->getName());
35         os << L"* " << name << L" " << ctx->paramstring;
36         ctx->flags |= SEND_TO_OTHERS | SEND_NO_PREFIX;
37 }
38
39 void cmd_privs(std::wostringstream &os,
40         ServerCommandContext *ctx)
41 {
42         if(ctx->parms.size() == 1)
43         {
44                 // Show our own real privs, without any adjustments
45                 // made for admin status
46                 os<<L"-!- " + narrow_to_wide(privsToString(
47                                 ctx->server->getPlayerAuthPrivs(ctx->player->getName())));
48                 return;
49         }
50
51         if((ctx->privs & PRIV_PRIVS) == 0)
52         {
53                 os<<L"-!- You don't have permission to do that";
54                 return;
55         }
56                 
57         Player *tp = ctx->env->getPlayer(wide_to_narrow(ctx->parms[1]).c_str());
58         if(tp == NULL)
59         {
60                 os<<L"-!- No such player";
61                 return;
62         }
63         
64         os<<L"-!- " + narrow_to_wide(privsToString(ctx->server->getPlayerAuthPrivs(tp->getName())));
65 }
66
67 void cmd_grantrevoke(std::wostringstream &os,
68         ServerCommandContext *ctx)
69 {
70         if(ctx->parms.size() != 3)
71         {
72                 os<<L"-!- Missing parameter";
73                 return;
74         }
75
76         if((ctx->privs & PRIV_PRIVS) == 0)
77         {
78                 os<<L"-!- You don't have permission to do that";
79                 return;
80         }
81
82         u64 newprivs = stringToPrivs(wide_to_narrow(ctx->parms[2]));
83         if(newprivs == PRIV_INVALID)
84         {
85                 os<<L"-!- Invalid privileges specified";
86                 return;
87         }
88
89         Player *tp = ctx->env->getPlayer(wide_to_narrow(ctx->parms[1]).c_str());
90         if(tp == NULL)
91         {
92                 os<<L"-!- No such player";
93                 return;
94         }
95         
96         std::string playername = wide_to_narrow(ctx->parms[1]);
97         u64 privs = ctx->server->getPlayerAuthPrivs(playername);
98
99         if(ctx->parms[0] == L"grant"){
100                 privs |= newprivs;
101                 actionstream<<ctx->player->getName()<<" grants "
102                                 <<wide_to_narrow(ctx->parms[2])<<" to "
103                                 <<playername<<std::endl;
104
105                 std::wstring msg;
106                 msg += narrow_to_wide(ctx->player->getName());
107                 msg += L" granted you the privilege \"";
108                 msg += ctx->parms[2];
109                 msg += L"\"";
110                 ctx->server->notifyPlayer(playername.c_str(), msg);
111         } else {
112                 privs &= ~newprivs;
113                 actionstream<<ctx->player->getName()<<" revokes "
114                                 <<wide_to_narrow(ctx->parms[2])<<" from "
115                                 <<playername<<std::endl;
116
117                 std::wstring msg;
118                 msg += narrow_to_wide(ctx->player->getName());
119                 msg += L" revoked from you the privilege \"";
120                 msg += ctx->parms[2];
121                 msg += L"\"";
122                 ctx->server->notifyPlayer(playername.c_str(), msg);
123         }
124         
125         ctx->server->setPlayerAuthPrivs(playername, privs);
126         
127         os<<L"-!- Privileges change to ";
128         os<<narrow_to_wide(privsToString(privs));
129 }
130
131 void cmd_time(std::wostringstream &os,
132         ServerCommandContext *ctx)
133 {
134         if(ctx->parms.size() != 2)
135         {
136                 os<<L"-!- Missing parameter";
137                 return;
138         }
139
140         if((ctx->privs & PRIV_SETTIME) ==0)
141         {
142                 os<<L"-!- You don't have permission to do that";
143                 return;
144         }
145
146         u32 time = stoi(wide_to_narrow(ctx->parms[1]));
147         ctx->server->setTimeOfDay(time);
148         os<<L"-!- time_of_day changed.";
149
150         actionstream<<ctx->player->getName()<<" sets time "
151                         <<time<<std::endl;
152 }
153
154 void cmd_shutdown(std::wostringstream &os,
155         ServerCommandContext *ctx)
156 {
157         if((ctx->privs & PRIV_SERVER) ==0)
158         {
159                 os<<L"-!- You don't have permission to do that";
160                 return;
161         }
162
163         actionstream<<ctx->player->getName()
164                         <<" shuts down server"<<std::endl;
165
166         ctx->server->requestShutdown();
167                                         
168         os<<L"*** Server shutting down (operator request)";
169         ctx->flags |= SEND_TO_OTHERS;
170 }
171
172 void cmd_setting(std::wostringstream &os,
173         ServerCommandContext *ctx)
174 {
175         if((ctx->privs & PRIV_SERVER) ==0)
176         {
177                 os<<L"-!- You don't have permission to do that";
178                 return;
179         }
180
181         /*std::string confline = wide_to_narrow(
182                         ctx->parms[1] + L" = " + ctx->params[2]);*/
183
184         std::string confline = wide_to_narrow(ctx->paramstring);
185         
186         actionstream<<ctx->player->getName()
187                         <<" sets: "<<confline<<std::endl;
188
189         g_settings->parseConfigLine(confline);
190         
191         ctx->server->saveConfig();
192
193         os<< L"-!- Setting changed and configuration saved.";
194 }
195
196 void cmd_teleport(std::wostringstream &os,
197         ServerCommandContext *ctx)
198 {
199         if((ctx->privs & PRIV_TELEPORT) ==0)
200         {
201                 os<<L"-!- You don't have permission to do that";
202                 return;
203         }
204
205         if(ctx->parms.size() != 2)
206         {
207                 os<<L"-!- Missing parameter";
208                 return;
209         }
210
211         std::vector<std::wstring> coords = str_split(ctx->parms[1], L',');
212         if(coords.size() != 3)
213         {
214                 os<<L"-!- You can only specify coordinates currently";
215                 return;
216         }
217
218         v3f dest(stoi(coords[0])*10, stoi(coords[1])*10, stoi(coords[2])*10);
219
220         actionstream<<ctx->player->getName()<<" teleports from "
221                         <<PP(ctx->player->getPosition()/BS)<<" to "
222                         <<PP(dest/BS)<<std::endl;
223
224         ctx->player->setPosition(dest);
225         ctx->server->SendMovePlayer(ctx->player);
226
227         os<< L"-!- Teleported.";
228 }
229
230 void cmd_banunban(std::wostringstream &os, ServerCommandContext *ctx)
231 {
232         if((ctx->privs & PRIV_BAN) == 0)
233         {
234                 os<<L"-!- You don't have permission to do that";
235                 return;
236         }
237
238         if(ctx->parms.size() < 2)
239         {
240                 std::string desc = ctx->server->getBanDescription("");
241                 os<<L"-!- Ban list: "<<narrow_to_wide(desc);
242                 return;
243         }
244         if(ctx->parms[0] == L"ban")
245         {
246                 Player *player = ctx->env->getPlayer(wide_to_narrow(ctx->parms[1]).c_str());
247
248                 if(player == NULL)
249                 {
250                         os<<L"-!- No such player";
251                         return;
252                 }
253
254                 con::Peer *peer = ctx->server->getPeerNoEx(player->peer_id);
255                 if(peer == NULL)
256                 {
257                         dstream<<__FUNCTION_NAME<<": peer was not found"<<std::endl;
258                         return;
259                 }
260                 std::string ip_string = peer->address.serializeString();
261                 ctx->server->setIpBanned(ip_string, player->getName());
262                 os<<L"-!- Banned "<<narrow_to_wide(ip_string)<<L"|"
263                                 <<narrow_to_wide(player->getName());
264
265                 actionstream<<ctx->player->getName()<<" bans "
266                                 <<player->getName()<<" / "<<ip_string<<std::endl;
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
281 std::wstring processServerCommand(ServerCommandContext *ctx)
282 {
283
284         std::wostringstream os(std::ios_base::binary);
285         ctx->flags = SEND_TO_SENDER;    // Default, unless we change it.
286
287         u64 privs = ctx->privs;
288
289         if(ctx->parms.size() == 0 || ctx->parms[0] == L"help")
290         {
291                 os<<L"-!- Available commands: ";
292                 os<<L"status privs ";
293                 if(privs & PRIV_SERVER)
294                         os<<L"shutdown setting ";
295                 if(privs & PRIV_SETTIME)
296                         os<<L" time";
297                 if(privs & PRIV_TELEPORT)
298                         os<<L" teleport";
299                 if(privs & PRIV_PRIVS)
300                         os<<L" grant revoke";
301                 if(privs & PRIV_BAN)
302                         os<<L" ban unban";
303         }
304         else if(ctx->parms[0] == L"status")
305         {
306                 cmd_status(os, ctx);
307         }
308         else if(ctx->parms[0] == L"privs")
309         {
310                 cmd_privs(os, ctx);
311         }
312         else if(ctx->parms[0] == L"grant" || ctx->parms[0] == L"revoke")
313         {
314                 cmd_grantrevoke(os, ctx);
315         }
316         else if(ctx->parms[0] == L"time")
317         {
318                 cmd_time(os, ctx);
319         }
320         else if(ctx->parms[0] == L"shutdown")
321         {
322                 cmd_shutdown(os, ctx);
323         }
324         else if(ctx->parms[0] == L"setting")
325         {
326                 cmd_setting(os, ctx);
327         }
328         else if(ctx->parms[0] == L"teleport")
329         {
330                 cmd_teleport(os, ctx);
331         }
332         else if(ctx->parms[0] == L"ban" || ctx->parms[0] == L"unban")
333         {
334                 cmd_banunban(os, ctx);
335         }
336         else if(ctx->parms[0] == L"me")
337         {
338                 cmd_me(os, ctx);
339         }
340         else
341         {
342                 os<<L"-!- Invalid command: " + ctx->parms[0];
343         }
344         return os.str();
345 }
346
347