diff --git a/.gitignore b/.gitignore index 85252655..1a19e711 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ sauer.log /config.cfg /*.sqlite +/storage + #stuff that comes after cmake . and make CMakeCache.txt CMakeFiles/ diff --git a/src/fpsgame/server.cpp b/src/fpsgame/server.cpp index fb637863..873f789b 100644 --- a/src/fpsgame/server.cpp +++ b/src/fpsgame/server.cpp @@ -1640,13 +1640,17 @@ namespace server void editpackethook(int cn, int type, packetbuf p) { int size = msgsizelookup(type); + int pos = p.len; std::vector packet; packet.push_back(cn); packet.push_back(type); - for(int i=0;istate.state==CS_ALIVE) smode->moved(cp, cp->state.o, cp->gameclip, pos, (flags&0x80)!=0); cp->state.o = pos; + cp->state.dir = (dir%360); cp->gameclip = (flags&0x80)!=0; } break; @@ -2085,6 +2090,7 @@ namespace server case N_EDITENT: { + editpackethook(ci->clientnum,type,p); int i = getint(p); loopk(3) getint(p); int type = getint(p); diff --git a/src/fpsgame/server.h b/src/fpsgame/server.h index 0fbce139..a0a772ed 100644 --- a/src/fpsgame/server.h +++ b/src/fpsgame/server.h @@ -112,6 +112,7 @@ namespace server struct gamestate : fpsstate { vec o; + int dir; int state, editstate; int lastdeath, lastspawn, lifesequence; int lastshot; diff --git a/src/pycontrol/servermodule.cpp b/src/pycontrol/servermodule.cpp index 8ca555bf..b04ce53d 100644 --- a/src/pycontrol/servermodule.cpp +++ b/src/pycontrol/servermodule.cpp @@ -21,7 +21,7 @@ #include "server.h" #include "sbcs.h" #include "stream.cpp" - +#include "stdio.h" #include namespace SbPy @@ -92,6 +92,32 @@ static PyObject *numClients(PyObject *self, PyObject *args) return Py_BuildValue("i", server::numclients()); } +static PyObject *playerPosition(PyObject *self, PyObject *args) +{ + int cn; + server::clientinfo *ci; + if(!PyArg_ParseTuple(args, "i", &cn)) + return 0; + ci = server::getinfo(cn); + if(!ci) + { + PyErr_SetString(PyExc_ValueError, "Invalid cn specified."); + return 0; + } + if(!ci->name) + { + PyErr_SetString(PyExc_RuntimeError, "Client cn is valid but has no name."); + return 0; + } + PyObject *pTuple = PyTuple_New(4); + PyObject *pInt; + PyTuple_SetItem(pTuple,0,PyInt_FromLong(ci->state.o.x)); + PyTuple_SetItem(pTuple,1,PyInt_FromLong(ci->state.o.y)); + PyTuple_SetItem(pTuple,2,PyInt_FromLong(ci->state.o.z)); + PyTuple_SetItem(pTuple,3,PyInt_FromLong(ci->state.dir)); + return pTuple; +} + static PyObject *clients(PyObject *self, PyObject *args) { server::clientinfo *ci; @@ -1020,6 +1046,7 @@ static PyMethodDef ModuleMethods[] = { {"clients", clients, METH_VARARGS, "List of client numbers."}, {"players", players, METH_VARARGS, "List of client numbers of active clients."}, {"spectators", spectators, METH_VARARGS, "List of client numbers of spectating clients."}, + {"playerPosition", playerPosition, METH_VARARGS, "Get the position of the player."}, {"playerMessage", playerMessage, METH_VARARGS, "Send a message to player."}, {"playerName", playerName, METH_VARARGS, "Get name of player from cn."}, {"playerSessionId", playerSessionId, METH_VARARGS, "Session ID of player."}, diff --git a/src/pyscripts/editing/ents.py b/src/pyscripts/editing/ents.py new file mode 100644 index 00000000..db6f6b0a --- /dev/null +++ b/src/pyscripts/editing/ents.py @@ -0,0 +1,28 @@ +"""This file contains the required functions for the editing features""" + +import base +from hypershade.cubescript import playerCS, CSCommand +from hyperserv.servercommands import ServerError + +editentnumber=base.packettypenumber("EDITENT") +editentlength=base.packettypes[editentnumber][1] +i=0 +imax=5000 +istart=5000 + +@CSCommand("ent","trusted") +def entcommand(caller, *args): + ent(args) + +def ent(args): + if len(args)==editentlength: + j=args[0] + args=args[1:] + elif len(args)==editentlength-1: + global i + i+=1 + i%=imax + j=i + else: + raise ServerError("EDITENT must have 9(if id is unspecified) or 10 arguments.") + base.packetSendingQueue.put((editentnumber,j+istart)+args) \ No newline at end of file diff --git a/src/pyscripts/hyperserv/notices.py b/src/pyscripts/hyperserv/notices.py index 45d6798e..7200f108 100644 --- a/src/pyscripts/hyperserv/notices.py +++ b/src/pyscripts/hyperserv/notices.py @@ -4,6 +4,7 @@ import hypershade from hypershade.cubescript import CSCommand, playerCS from hypershade.util import modeName, mastermodeName, formatCaller +from hypershade.usersession import UserSessionManager muted_cns = [] @@ -85,6 +86,10 @@ def noticePlayerMuted(caller,boolean,target): def noticePlayerKicked(caller,cn): serverNotice("%s got kicked by %s." % (formatCaller(("ingame",cn)),formatCaller(caller))) +@eventHandler("player_kick_failed") +def noticePlayerKickFailed(caller,cn): + serverNotice("%s attempted to kick %s but failed since %s is an %s." % (formatCaller(caller),formatCaller(("ingame",cn)),formatCaller(("ingame",cn)),UserSessionManager[("ingame",cn)][1])) + @eventHandler("player_uploaded_map") def noticePlayerUploadedMap(cn): serverNotice("%s has sent the map." % (formatCaller(("ingame",cn)),)) diff --git a/src/pyscripts/hyperserv/plugins.py b/src/pyscripts/hyperserv/plugins.py index 743ff253..7ff1cced 100644 --- a/src/pyscripts/hyperserv/plugins.py +++ b/src/pyscripts/hyperserv/plugins.py @@ -6,6 +6,7 @@ import hyperserv.clientcommands import hyperserv.servercommands import hyperserv.ingame +import hyperserv.position import editing diff --git a/src/pyscripts/hyperserv/position.py b/src/pyscripts/hyperserv/position.py new file mode 100644 index 00000000..6c5f947b --- /dev/null +++ b/src/pyscripts/hyperserv/position.py @@ -0,0 +1,23 @@ +"""This file contains the required functions for the editing features""" + +import sbserver +from hypershade.cubescript import playerCS, CSCommand +from hyperserv.servercommands import ServerError + +def merge(a): + return (reduce(lambda y,x: x*256+y, a, 0),) + +def getPosition(cn): + return sbserver.playerPosition(cn)[:3] + +def getYaw(cn): + return sbserver.playerPosition(cn)[3] + +@CSCommand("pos","master") +def getPositionCS(caller, cn=None): + if cn is None: + if caller[0]!="ingame": + raise ServerError("You are not ingame. Please specify cn.") + cn=int(caller[1]) + return "Pos: %s, Yaw: %s" %(getPosition(int(cn)),getYaw(int(cn))) + diff --git a/src/pyscripts/hyperserv/servercommands.py b/src/pyscripts/hyperserv/servercommands.py index a705ab50..3cec5955 100644 --- a/src/pyscripts/hyperserv/servercommands.py +++ b/src/pyscripts/hyperserv/servercommands.py @@ -9,7 +9,7 @@ from hypershade.config import config from hypershade.cubescript import systemCS, CSCommand, playerCS -from hypershade.usersession import UserSessionManager +from hypershade.usersession import UserSessionManager, PermissionError from hypershade.util import ipLongToString, modeNumber, mastermodeNumber, formatCaller from hypershade.files import openfile @@ -70,7 +70,11 @@ def relinquish(caller): def kick(caller,cn): """Kicks another player; however, this command does not work on players with higher permission. Kicking a player also gives them a 60 minute ban.""" cn=int(cn) - UserSessionManager.checkPermissions(caller,UserSessionManager[("ingame",cn)][1]) #check if the other person is more privileged + try: + UserSessionManager.checkPermissions(caller,UserSessionManager[("ingame",cn)][1]) #check if the other person is more privileged + except PermissionError: + triggerServerEvent("player_kick_failed",[caller,cn]) + raise ban(caller,sbserver.playerName(cn),"kicked by %s" % formatCaller(caller)) triggerServerEvent("player_kicked",[caller,cn]) diff --git a/src/pyscripts/hypershade/bandatabase.py b/src/pyscripts/hypershade/bandatabase.py index b470e23b..989f25ca 100644 --- a/src/pyscripts/hypershade/bandatabase.py +++ b/src/pyscripts/hypershade/bandatabase.py @@ -8,7 +8,7 @@ def newfunction(*args): ban=results if expired(ban): del bandatabase[ban[0]] - raise KeyError("No such ban: %s" % (ban[0])) + raise KeyError("No such ban: %s", (ban[0])) return formatExpiration(ban) else: def checkExpired(ban): @@ -38,10 +38,10 @@ def items(self): @checkForExpired def __getitem__(self,name): - database.query('SELECT * FROM `bans` WHERE `id` = "%s" ORDER BY `bans`.`expires` DESC LIMIT 1' % (name)) + database.query('SELECT * FROM `bans` WHERE `id` = %s ORDER BY `bans`.`expires` DESC LIMIT 1', (name)) if database.cursor.rowcount==0: - raise KeyError("No such ban: %s" % (name)) + raise KeyError("No such ban: %s", (name)) return database.cursor.fetchone() @@ -50,10 +50,10 @@ def __setitem__(self,name,values): del self[name] except: pass - database.query('INSERT INTO `bans` VALUES ("%s","%s","%s")' % (name,values[0],values[1])) + database.query('INSERT INTO `bans` VALUES (%s,%s,%s)', (name,values[0],values[1])) def __delitem__(self,name): - database.query('DELETE FROM `bans` WHERE `id` = "%s"' % (name)) + database.query('DELETE FROM `bans` WHERE `id` = %s', (name)) def cleargbans(self): database.query('DELETE FROM `bans` WHERE `reason` = "gban"') @@ -69,8 +69,8 @@ def search(self,names): if type(names) is str: #probably a mistake, only one is wanted return (self[names],) - string = ' OR '.join(map(lambda name: '`id` = "%s"' % name,names)) - database.query('SELECT * FROM `bans` WHERE %s ORDER BY `bans`.`expires` DESC' % (string)) + string = ' OR '.join(('`id` = %s',)*len(names)) + database.query('SELECT * FROM `bans` WHERE %s ORDER BY `bans`.`expires` DESC' % string, names) return tuple(database.cursor.fetchall()) def formatExpiration(time): diff --git a/src/pyscripts/hypershade/userdatabase.py b/src/pyscripts/hypershade/userdatabase.py index 7abda9bb..e6c78b6f 100644 --- a/src/pyscripts/hypershade/userdatabase.py +++ b/src/pyscripts/hypershade/userdatabase.py @@ -10,10 +10,10 @@ def items(self): return tuple(database.cursor.fetchall()) def __getitem__(self,username): - database.query('SELECT `user` FROM `users` WHERE `user` = "%s" AND `key` = "privileges"' % (username)) + database.query('SELECT `user` FROM `users` WHERE `user` = %s AND `key` = "privileges"', (username,)) if database.cursor.rowcount==0: - raise KeyError("No such user: %s" % (username)) + raise KeyError("No such user: %s" % (username,)) return User(username) @@ -25,13 +25,13 @@ def __setitem__(self,username,privileges): User(username)["privileges"]=privileges def __delitem__(self,username): - database.query('DELETE FROM `users` WHERE `user` = "%s"' % (username)) + database.query('DELETE FROM `users` WHERE `user` = %s', (username,)) def __repr__(self): return repr(self.items()) def search(self,key,value): - database.query('SELECT `user` FROM `users` WHERE `key` = "%s" and `value` = "%s"' % (key, value)) + database.query('SELECT `user` FROM `users` WHERE `key` = %s and `value` = %s', (key, value)) result=database.cursor.fetchone() if result is not None: return self[result[0]] @@ -47,11 +47,11 @@ def __iter__(self): yield row[0] def items(self): - database.query('SELECT `key`,`value` FROM `users` WHERE `user` = "%s"' % (self.username)) + database.query('SELECT `key`,`value` FROM `users` WHERE `user` = %s', (self.username,)) return (("username",self.username),)+tuple(database.cursor.fetchall()) def __getitem__(self,key): - database.query('SELECT value FROM `users` WHERE `user` = "%s" AND `key` = "%s"' % (self.username,key)) + database.query('SELECT value FROM `users` WHERE `user` = %s AND `key` = %s', (self.username,key)) return tuple(row[0] for row in database.cursor.fetchall()) def __setitem__(self,key,values): @@ -60,10 +60,10 @@ def __setitem__(self,key,values): #probably a mistake, just one value is wanted values=(values,) for value in values: - database.query('INSERT INTO `users` VALUES ("%s","%s","%s")' % (self.username,key,value)) + database.query('INSERT INTO `users` VALUES (%s,%s,%s)', (self.username,key,value)) def __delitem__(self, key): - database.query('DELETE FROM `users` WHERE `user` = "%s" AND `key` = "%s"' % (self.username,key)) + database.query('DELETE FROM `users` WHERE `user` = %s AND `key` = %s', (self.username,key)) def __repr__(self): return repr(self.items()) diff --git a/src/pyscripts/plugins/heatmap.py b/src/pyscripts/plugins/heatmap.py new file mode 100755 index 00000000..5e21a984 --- /dev/null +++ b/src/pyscripts/plugins/heatmap.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +from hypershade.cubescript import playerCS, CSCommand +from hyperserv.servercommands import ServerError +from hyperserv.position import getPosition +from editing.base import sendpacket +from editing.ents import ent + +flamecolours = { + "good": 0, + "evil": 15, + "neutral": 240, +} + +@CSCommand("mark","trusted") +def mark(caller,color): + cn=int(caller[1]) + color=flamecolours[color] + position=map(lambda a: a*16, getPosition(cn)) + entity=(position[0],position[1],position[2]+64,5,0,0,0,color,0) + ent(entity) diff --git a/src/pyscripts/plugins/irc.py b/src/pyscripts/plugins/irc.py index ed569d1f..698464d4 100755 --- a/src/pyscripts/plugins/irc.py +++ b/src/pyscripts/plugins/irc.py @@ -33,7 +33,7 @@ def left(self, channel): self.joined_channels.remove(channel) def broadcast(self, message): for channel in self.joined_channels: - self.say(channel, message) + self.say(channel, message, 256) def privmsg(self, user, channel, msg): user = user.split('!', 1)[0] if channel == self.nickname: