Multiverse/config/common/proxy.py
From Multiverse
Overview
The common/proxy.py script defines command handlers ("slash commands"). For more information, see Defining Command Handlers.
Code
This section consists of an annotated listing of the code in mv-home/config/common/proxy.py.
Imports and initialization
from java.util import *
from java.lang import *
from multiverse.mars import *
from multiverse.mars.core import *
from multiverse.mars.objects import *
from multiverse.mars.util import *
from multiverse.mars.plugins import *
from multiverse.msgsys import *
from multiverse.server.math import *
from multiverse.server.plugins import *
from multiverse.server.events import *
from multiverse.server.objects import *
from multiverse.server.engine import *
from multiverse.server.util import *
False=0
True=1
AnimationClient.setAnimationEffect("PlayAnimation")
# Register a plugin and create a subscription for it
# myPlugin = EnginePlugin("myPlugin")
# Engine.registerPlugin(myPlugin)
# myPlugin.createSubscription(myHandler(), MessageType.intern("myMsgType"))
Engine.registerPlugin("multiverse.mars.plugins.MarsProxyPlugin")
proxyPlugin = Engine.getPlugin("Proxy1")
PersistCommand
class PersistCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
playerOid = cmdEvent.getObjectOid()
cmd = cmdEvent.getCommand()
splitCmd = cmd.split(" ")
objOid = int(splitCmd[1])
Log.debug("PersistCommand: playerOid=" + str(playerOid) + ", objOid=" + str(objOid))
# send out a set persist message
ObjectManagerClient.setPersistenceFlag(objOid,
Boolean.TRUE)
WorldManagerClient.sendObjChatMsg(playerOid, 1, "persisted obj " + str(objOid))
return None
GenerateCommand
class GenerateCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
playerOid = cmdEvent.getObjectOid()
# The args are template name
cmd = cmdEvent.getCommand()
splitCmd = cmd.split(" ")
templateName = splitCmd[1]
Log.debug("GenerateCommand: player=" + str(playerOid) + ", template=" + templateName)
# get the player's loc
objInfo = WorldManagerClient.getObjectInfo(playerOid)
loc = objInfo.loc
loc.add(1000,0,0)
Log.debug("GenerateCommand: player=" + str(playerOid) + ", loc=" + loc.toString())
# generate the object
objOid = ObjectManagerClient.generateObject(templateName, loc)
Log.debug("GenerateCommand: player=" + str(playerOid) + ", generated obj oid=" + str(objOid))
# spawn object
rv = WorldManagerClient.spawn(objOid)
Log.debug("GenerateCommand: player=" + str(playerOid) + ", spawned obj rv=" + str(rv))
WorldManagerClient.sendObjChatMsg(playerOid, 1, "generated oid=" + str(objOid))
return None
ThreadStatsCommand
class ThreadStatsCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
global proxyPlugin;
cmd = cmdEvent.getCommand()
playerOid = cmdEvent.getObjectOid()
targetOid = cmdEvent.getTarget()
Log.debug("ThreadStatsCommand: playerOid=" + str(playerOid) + ", " + proxyPlugin.getCurrentThreads().toString())
InventoryClient.activateObject(targetOid,
playerOid)
WorldManagerClient.sendObjChatMsg(playerOid, 1, "threadstats=" + proxyPlugin.getCurrentThreads().toString())
return None
ConcludeCommand
class ConcludeCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
cmd = cmdEvent.getCommand()
playerOid = cmdEvent.getObjectOid()
targetOid = cmdEvent.getTarget()
Log.debug("ConcludeCommand: cmd=" + cmd)
rv = QuestClient.requestConclude(targetOid,
playerOid)
return None
AddParticleEffectCommand
class AddParticleEffectCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
cmd = cmdEvent.getCommand()
playerOid = cmdEvent.getObjectOid()
targetOid = cmdEvent.getTarget()
Log.debug("AddParticleEffectCommand: cmd=" + cmd)
splitCmd = cmd.split(" ")
attachName = splitCmd[1]
effectName = splitCmd[2]
vel = 5
size = 5
booleans = 0
if (len(splitCmd) >= 4) :
vel = float(splitCmd[3])
if (len(splitCmd) >= 5) :
size = float(splitCmd[4])
if (len(splitCmd) >= 6) :
booleans = int(splitCmd[5])
r = 255
g = 255
b = 255
if (len(splitCmd) >= 7) :
r = splitCmd[6]
if (len(splitCmd) >= 8) :
g = splitCmd[7]
if (len(splitCmd) >= 9) :
b = splitCmd[8]
color = Color(int(r), int(g), int(b))
rv = AnimationClient.addParticleEffect(playerOid,
attachName,
effectName,
Quaternion(0,0,0,1),
vel,
size,
booleans,
color)
return None
LootCommand
class LootCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
cmd = cmdEvent.getCommand()
playerOid = cmdEvent.getObjectOid()
targetOid = cmdEvent.getTarget()
Log.debug("LootCommand: cmd=" + cmd)
rv = InventoryClient.lootAll(playerOid,
targetOid)
WorldManagerClient.sendObjChatMsg(playerOid, 0, "proxy.py:lootAll=" + str(rv))
return None
SetLocCommand
class SetLocCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
cmd = cmdEvent.getCommand()
Log.debug("SetLocCommand: cmd=" + cmd)
splitCmd = cmd.split(" ")
x = int(splitCmd[1])
y = int(splitCmd[2])
z = int(splitCmd[3])
wnode = BasicWorldNode()
wnode.setLoc(Point(x,y,z))
# tell the worldmanager we've moved
# this should update everyone near me
WorldManagerClient.updateWorldNode(cmdEvent.getObjectOid(), wnode, True)
return None
GotoCommand
The Goto command moves the player character to the specified waypoint in the world. The user invokes it from the client as follows:
/goto waypointName
where waypointName is a defined waypoint.
class GotoCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
cmd = cmdEvent.getCommand()
playerOid = cmdEvent.getObjectOid()
Log.debug("GotoCommand: cmd=" + cmd)
splitCmd = cmd.split(" ")
markerName = splitCmd[1]
Log.debug("GotoCommand: got goto command, to marker=" + markerName)
current = WorldManagerClient.getWorldNode(playerOid) instanceOid = current.getInstanceOid()
marker = InstanceClient.getMarker(instanceOid, markerName)
if (marker == None):
WorldManagerClient.sendObjChatMsg(playerOid, 0, "Unknown marker")
return
Log.debug("GotoCommand: marker " + markerName + "=" + marker.toString())
wnode = BasicWorldNode()
wnode.setLoc(marker.getPoint())
wnode.setOrientation(marker.getOrientation())
# tell the worldmanager we've moved
# this should update everyone near me
WorldManagerClient.updateWorldNode(playerOid, wnode, True)
CreateItemCommand
class CreateItemCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
cmd = cmdEvent.getCommand()
# the template name is whatever is after the space
template = cmd[cmd.index(' ')+1:]
Log.debug("CreateItemSubObjCommand: template=" + template)
playerOid = cmdEvent.getObjectOid()
bagOid = WorldManagerClient.getObjectProperty(playerOid, InventoryPlugin.INVENTORY_PROP_BAG_KEY)
Log.debug("CreateItemSubObjCommand: bagOid=" + str(bagOid))
# generate the object
Log.debug("CreateItemSubObjCommand: templ=" + template + ", generating object")
itemOid = ObjectManagerClient.generateObject(template, Template())
# add to inventory
Log.debug("CreateItemSubObjCommand: createitem: oid=" + str(itemOid) + ", bagOid=" + str(bagOid) + ", adding to inventory")
rv = InventoryClient.addItem(playerOid, playerOid, playerOid, itemOid)
Log.debug("CommandPlugin: createitem: oid=" + str(itemOid) + ", added, rv=" + str(rv))
WorldManagerClient.sendObjChatMsg(playerOid, 1, "added item" + str(rv))
return None
SetMeshCommand
class SetMeshCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
cmd = cmdEvent.getCommand()
playerOid = cmdEvent.getObjectOid()
mesh = cmd[cmd.index(' ')+1:]
submeshes = LinkedList()
Log.debug("/setmesh: oid=" + str(playerOid) + " to: " + mesh)
WorldManagerClient.modifyDisplayContext(playerOid,
WorldManagerClient.modifyDisplayContextActionReplace,
mesh,
submeshes)
return None
ReleaseCommand
class ReleaseCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
playerOid = cmdEvent.getObjectOid()
Log.debug("/release: oid=" + str(playerOid))
CombatClient.releaseObject(playerOid)
return None
WhoCommand
class WhoCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
global proxyPlugin;
playerOid = cmdEvent.getObjectOid()
playerNames = proxyPlugin.getPlayerNames()
Log.debug("/who: oid=" + str(playerOid) + ": returning "+str(playerNames.size())+" players")
response = "players\n------------\n"
for name in playerNames:
response = response + name + "\n"
response = response + str(playerNames.size()) + " players\n"
WorldManagerClient.sendObjChatMsg(playerOid, 0, response)
return None
PlayerCountCommand
class PlayerCountCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
global proxyPlugin;
playerOid = cmdEvent.getObjectOid()
playerNames = proxyPlugin.getPlayerNames()
Log.debug("/playercount: oid=" + str(playerOid) + ": returning "+str(playerNames.size())+" players")
response = str(playerNames.size()) + " players\n"
ProxyPlugin.sendObjChatMsg(playerOid, 0, response)
return None
ParmCommand
The "/parm" command accepts a series of name/value pairs, separated by spaces.
class ParmCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
playerOid = cmdEvent.getObjectOid()
cmd = cmdEvent.getCommand()
splitCmd = cmd.split(" ")
count = (len(splitCmd) - 1) / 2
i = -1
msg = WorldManagerClient.TargetedExtensionMessage(playerOid)
msg.setProperty("ext_msg_type", "ClientParameter")
for s in splitCmd:
if (i != -1):
if ((i & 1) == 0):
n = s
else:
msg.setProperty(n, s)
i = i + 1
Engine.getAgent().sendBroadcast(msg)
return None
To set a parameter in the client using the command that runs on the server side, type
/parm parameterName parameterValue
For example
/parm CollisionAPI.MinInchesToObstacle 42.0
SysCommand
class SysCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
cmd = cmdEvent.getCommand()
msg = cmd[cmd.index(' ')+1:]
Log.debug("SysCommand: msg=" + msg)
WorldManagerClient.sendSysChatMsg("System: " + msg)
return None
DirLightCommand
class DirLightCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
global proxyPlugin;
playerOid = cmdEvent.getObjectOid()
cmd = cmdEvent.getCommand()
splitCmd = cmd.split(" ")
x = Float.valueOf(splitCmd[1])
y = Float.valueOf(splitCmd[2])
z = Float.valueOf(splitCmd[3])
Log.debug("DirLightCommand: playerOid=" + str(playerOid) +
", x=" + str(x) +
", y=" + str(y) +
", z=" + str(z))
grey = Color(140, 128, 128)
dirlight = DirectionalLight("dirlight")
dirlight.setDiffuse(grey)
dirlight.setSpecular(grey)
dirlight.setAttenuationRange(1000000)
dirlight.setAttenuationConstant(1)
dirlight.setAttenuationLinear(0)
dirlight.setAttenuationQuadradic(0)
vector = MVVector(x,y,z)
dirlight.setLightOrientation(Quaternion.fromAngleAxis(-1, vector))
lightEvent = NewLightEvent()
lightEvent.setObjectOid(playerOid)
lightEvent.setLight(dirlight)
playerOids = proxyPlugin.getPlayerOids()
for oid in playerOids:
conMap = proxyPlugin.getConnectionMap()
con = conMap.getConnection(oid)
Log.debug("DirLightCommand: sending light " +
dirlight.toString() +
" to oid " + str(oid))
con.send(lightEvent.toBytes())
return None
FindCommand
class FindCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
playerOid = cmdEvent.getObjectOid()
cmd = cmdEvent.getCommand()
itemTemplate = cmd[cmd.index(' ')+1:]
itemOid = InventoryClient.findItem(playerOid, itemTemplate)
if (itemOid == None):
WorldManagerClient.sendObjChatMsg(playerOid, 0, "item not found")
else:
WorldManagerClient.sendObjChatMsg(playerOid, 0, itemTemplate + ":" + str(itemOid))
FindWeaponCommand
class FindWeaponCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
playerOid = cmdEvent.getObjectOid()
itemOid = MarsInventoryClient.findItem(playerOid, MarsEquipSlot.PRIMARYWEAPON)
if (itemOid == None):
WorldManagerClient.sendObjChatMsg(playerOid, 0, "item not found")
else:
WorldManagerClient.sendObjChatMsg(playerOid, 0, "weapon:" + str(itemOid))
RemoveCommand
class RemoveCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
playerOid = cmdEvent.getObjectOid()
cmd = cmdEvent.getCommand()
itemTemplate = cmd[cmd.index(' ')+1:]
itemOid = InventoryClient.removeItem(playerOid, itemTemplate)
if (itemOid == None):
WorldManagerClient.sendObjChatMsg(playerOid, 0, "item not found")
else:
WorldManagerClient.sendObjChatMsg(playerOid, 0, itemTemplate + ":" + str(itemOid))
AbilityCommand
class AbilityCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
playerOid = cmdEvent.getObjectOid()
targetOid = cmdEvent.getTarget()
cmd = cmdEvent.getCommand()
abilityName = cmd[cmd.index(' ')+1:]
CombatClient.startAbility(abilityName, playerOid, targetOid, None)
NoMoveCommand
class NoMoveCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
playerOid = cmdEvent.getObjectOid()
targetOid = cmdEvent.getTarget()
cmd = cmdEvent.getCommand()
nomove = cmd[cmd.index(' ')+1:]
if nomove == "on":
WorldManagerClient.setObjectProperty(targetOid, "world.nomove", Boolean(True))
else:
WorldManagerClient.setObjectProperty(targetOid, "world.nomove", Boolean(False))
ResetQuestCommand
class ResetQuestCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
playerOid = cmdEvent.getObjectOid()
QuestClient.resetQuests(playerOid)
DumpStacksCommand
class DumpStacksCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
msg = Message(EnginePlugin.MSG_TYPE_DUMP_ALL_THREAD_STACKS)
Engine.getAgent().sendBroadcast(msg)
TradeStartCommand
class TradeStartCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
playerOid = cmdEvent.getObjectOid()
targetOid = cmdEvent.getTarget()
MarsInventoryClient.tradeStart(playerOid, targetOid)
StuckCommand
Occaisionally, a player can get "stuck" in a collision volume, usually by moving into a new area before the Client loads buildings and other objects with collision volumes. Once the player is in this state, the avatar can't move, because the Multiverse collision system prevents it. If an avatar has been in this situation for five seconds, the chat window will display the message: "Executing /stuck command because player has been in a collision volume for 5000 milliseconds," then the Client will automatically issue the "/stuck" command that calls the server StuckCommand method.
If the world contains a marker named "stuck", then the player is moved to that location. If not, then the player avatar will be moved to the origin (0, 0, 0).
To change the time between getting stuck and executing StuckCommand, set the value of the client parameter InputHandler.MillisecondsStuckBeforeGotoStuck. The default value of this parameter is 5000 milliseconds. To disable "stuck" support, set InputHandler.MillisecondsStuckBeforeGotoStuck to zero (0).
For more information on Client parameters, see Client Parameters.
class StuckCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
wnode = BasicWorldNode()
playerOid = cmdEvent.getObjectOid()
current = WorldManagerClient.getWorldNode(playerOid)
instanceOid = current.getInstanceOid()
marker = InstanceClient.getMarker(instanceOid, "stuck")
if (marker != None):
wnode.setLoc(marker.getPoint())
wnode.setOrientation(marker.getOrientation())
Log.debug("StuckCommand: marker stuck = " + marker.toString())
else:
wnode.setLoc(Point(0, 0, 0))
Log.debug("StuckCommand: no marker stuck, so going to (0, 0, 0)")
# tell the worldmanager we've moved
WorldManagerClient.updateWorldNode(cmdEvent.getObjectOid(), wnode, True)
TestCommand
# tests should send a chat message back with "test success" or "test failure"
class TestCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
cmd = cmdEvent.getCommand()
playerOid = cmdEvent.getObjectOid()
cmd = cmdEvent.getCommand()
splitCmd = cmd.split(" ")
testName = splitCmd[1]
if (testName == "persistKey") :
# example /test persistKey testKey
key = splitCmd[2]
self.testKeywordPersistence(playerOid, key)
else :
Log.error("TestCommand: unknown test " + testName)
def testKeywordPersistence(self, playerOid, key) :
testNamespace = Namespace.intern("testNamespace")
saveEntity = Entity("saveEntity")
saveEntity.setProperty("sample_property", "sample_value")
if (not ObjectManagerClient.saveObjectData(key,
saveEntity,
testNamespace)) :
Log.error("testKeywordPersistence failed on saving")
WorldManagerClient.sendObjChatMsg(playerOid, 0, "test failure")
return
loadEntity = ObjectManagerClient.loadObjectData(key)
if (loadEntity == None) :
Log.error("testKeywordPersistence failed on loading, got null")
WorldManagerClient.sendObjChatMsg(playerOid, 0, "test failure")
return
val = loadEntity.getProperty("sample_property")
if (val != "sample_value") :
Log.error("testKeywordPersistence failed, value=" + val)
WorldManagerClient.sendObjChatMsg(playerOid, 0, "test failure")
return
Log.error("testKeywordPersistence: test passed")
WorldManagerClient.sendObjChatMsg(playerOid, 0, "test success")
# Display the server's notion of the orientation of a targeted entity as a chat message
OrientationCommand
class OrientationCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
playerOid = cmdEvent.getObjectOid()
targetOid = cmdEvent.getTarget()
targetObj = WorldManagerClient.getObjectInfo(targetOid)
WorldManagerClient.sendObjChatMsg(playerOid, 0, "Orientation: " + str(targetObj.orient))
DebugOidCommand
Enable debugging for a single OID. If no argument is given, then the targeted object OID is used.
Subject to change - enables some limited arbitrary debugging. May change or be removed in the next release.
class DebugOidCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
playerOid = cmdEvent.getObjectOid()
cmd = cmdEvent.getCommand().split(" ");
if len(cmd) > 1:
cmd = cmd[1]
else:
cmd = ""
objOid = 0
try:
if cmd != "":
objOid = int(cmd)
except ValueError:
WorldManagerClient.sendObjChatMsg(playerOid, 0, "Invalid OID");
return
except TypeError:
pass
if objOid == 0:
World.DEBUG_OID = cmdEvent.getTarget()
else:
World.DEBUG_OID = objOid
WorldManagerClient.sendObjChatMsg(playerOid, 0, "DEBUG_OID = "+str(World.DEBUG_OID))
UnknownCommand
This command is called if the user enters an unknown slash command. It displays the message "Unknown command" in the chat window.
class UnknownCommand (ProxyPlugin.CommandParser):
def parse(self, cmdEvent):
playerOid = cmdEvent.getObjectOid()
WorldManagerClient.sendObjChatMsg(playerOid, 0, "Unknown cmd " + cmdEvent.getCommand())
Registrations
This section registers all the commands previously defined, and associates them with the actual slash command that the user must enter.
proxyPlugin.registerCommand("/resetquests", ResetQuestCommand())
proxyPlugin.registerCommand("/nomove", NoMoveCommand())
proxyPlugin.registerCommand("/goto", GotoCommand())
proxyPlugin.registerCommand("/createitem", CreateItemCommand())
proxyPlugin.registerCommand("/setmesh", SetMeshCommand())
proxyPlugin.registerCommand("/setloc", SetLocCommand())
proxyPlugin.registerCommand("/lootall", LootCommand())
proxyPlugin.registerCommand("/addParticle", AddParticleEffectCommand())
proxyPlugin.registerCommand("/release", ReleaseCommand())
proxyPlugin.registerCommand("/conclude", ConcludeCommand())
proxyPlugin.registerCommand("/who", WhoCommand())
proxyPlugin.registerCommand("/playercount", PlayerCountCommand())
proxyPlugin.registerCommand("/parm", ParmCommand())
proxyPlugin.registerCommand("/sys", SysCommand())
proxyPlugin.registerCommand("/dirlight", DirLightCommand())
proxyPlugin.registerCommand("/threadstats", ThreadStatsCommand())
proxyPlugin.registerCommand("/find", FindCommand())
proxyPlugin.registerCommand("/remove", RemoveCommand())
proxyPlugin.registerCommand("/findweapon", FindWeaponCommand())
proxyPlugin.registerCommand("/ability", AbilityCommand())
proxyPlugin.registerCommand("/generate", GenerateCommand())
proxyPlugin.registerCommand("/persist", PersistCommand())
proxyPlugin.registerCommand("/dumpstacks", DumpStacksCommand())
proxyPlugin.registerCommand("/trade", TradeStartCommand())
proxyPlugin.registerCommand("/stuck", StuckCommand())
proxyPlugin.registerCommand("/test", TestCommand())
proxyPlugin.registerCommand("/orientation", OrientationCommand())
proxyPlugin.registerCommand("/debugoid", DebugOidCommand())
proxyPlugin.registerCommand("/unknownCmd", UnknownCommand())
