def __init__(self, keyboard): self.oP = OutPipe("TypingHandler", 0) self.eI = EngineInterface() self.keyboard = keyboard self.letters = { self.eI.e.AKEY: "a", self.eI.e.BKEY: "b", self.eI.e.CKEY: "c", self.eI.e.DKEY: "d", self.eI.e.EKEY: "e", self.eI.e.FKEY: "f", self.eI.e.GKEY: "g", self.eI.e.HKEY: "h", self.eI.e.IKEY: "i", self.eI.e.JKEY: "j", self.eI.e.KKEY: "k", self.eI.e.LKEY: "l", self.eI.e.MKEY: "m", self.eI.e.NKEY: "n", self.eI.e.OKEY: "o", self.eI.e.PKEY: "p", self.eI.e.QKEY: "q", self.eI.e.RKEY: "r", self.eI.e.SKEY: "s", self.eI.e.TKEY: "t", self.eI.e.UKEY: "u", self.eI.e.VKEY: "v", self.eI.e.WKEY: "w", self.eI.e.XKEY: "x", self.eI.e.YKEY: "y", self.eI.e.ZKEY: "z", } self.specials = { self.eI.e.ZEROKEY: "0", self.eI.e.ONEKEY: "1", self.eI.e.TWOKEY: "2", self.eI.e.THREEKEY: "3", self.eI.e.FOURKEY: "4", self.eI.e.FIVEKEY: "5", self.eI.e.SIXKEY: "6", self.eI.e.SEVENKEY: "7", self.eI.e.EIGHTKEY: "8", self.eI.e.NINEKEY: "9", self.eI.e.ACCENTGRAVEKEY: "`", self.eI.e.BACKSLASHKEY: "\\", self.eI.e.COMMAKEY: ",", self.eI.e.EQUALKEY: "=", self.eI.e.LEFTBRACKETKEY: "[", self.eI.e.MINUSKEY: "-", self.eI.e.PERIODKEY: ".", self.eI.e.QUOTEKEY: "'", self.eI.e.RIGHTBRACKETKEY: "]", self.eI.e.SEMICOLONKEY: ";", self.eI.e.SLASHKEY: "/", self.eI.e.SPACEKEY: " ", } self.oP("Initialized.")
class Interface(): def __init__(self, name, resource, scriptName): self.oP = OutPipe("Interface - " + name, 0) self.eI = EngineInterface(objectMode=False) self.sE = ScriptExecuter() self.name = name self.gameObject = None self.sE.addContext("Interface", self) self.sE.execute(scriptName) self.eI.getGlobal("addToQueue")(resource, name, self) if hasattr(self, "init"): self.init() self.oP("Added interface %s." % name) def __str__(self): return self.name def __repr__(self): return self.name def kill(self): self.eI.removeInterface(self.name)
class VideoPlayer(): def __init__(self): self.oP = OutPipe("VideoPlayer", 0) self.eI = EngineInterface() self.oP("Initialized.") def playVideo(self, video): playVideo = self.eI.getGlobal("playVideo") if playVideo: self.eI.l.globalDict["launcher"].sound.playVideoAudio(video) playVideo(VIDEO_PATH + video + VIDEO_EXT) self.oP("Requested video playback.") def stopVideo(self): stopVideo = self.eI.getGlobal("stopVideo") if stopVideo: self.eI.l.globalDict["launcher"].sound.stopVideoAudio() stopVideo() self.oP("Stopped video playback.") def loop(self): isVideoFinished = self.eI.getGlobal("isVideoFinished") if isVideoFinished: if isVideoFinished(): self.oP("Video end detected, stopping video.") self.stopVideo()
def __init__(self, master): self.oP = OutPipe("Localizer", 0) self.eI = EngineInterface() self.master = master self.oldLanguage = "" self.oldObjectCount = 0 self.oP("Initialized.")
def __init__(self): self.oP = OutPipe("SoundEngine", 0) self.eI = EngineInterface() self.sD = SubtitleDrawer(self) self.subtitles = 1 self.language = "en" self.device = aud.device() self.sounds = {} self.dialogs = {} self.music = None self.musicHandle = None self.playbacks = [] self.dialogPlaybacks = [] self.videoAudio = None self.masterVolume = 1.0 self.dialogVolume = 1.0 self.musicVolume = 1.0 self.soundVolume = 1.0 self.setMasterVolume(1.0) self.oP("Initialized.")
def __init__(self): self.oP = OutPipe("InputReceiver", 0) self.cR = ConfigReader(GAME_PATH + "controls") self.sE = ScriptExecuter() self.eI = EngineInterface(objectMode=False) self.keyboard = self.eI.getKeyboard() self.mouse = self.eI.getMouse() self.tH = TypingHandler(self.keyboard) self.pairs = {} self.responses = {} self.oldKeyboard = self.keyboard.events self.oldMouse = self.mouse.events self.sE.addContext("Input", self) self.sE.execute(INPUT_PATH + "csp") self.sE.execute(INPUT_PATH + "input") self.keyEvents = [] self.readControls() self.locked = False self.xsens = 50 self.ysens = 50 self.inverted = 0 self.predict = False self.recent = {} self.oP("Initialized.")
class SubtitleDrawer(): def __init__(self, master): self.oP = OutPipe("SubtitleDrawer", 0) self.eI = EngineInterface() self.master = master self.currentSubtitle = None self.oP("Initialized.") def drawSubtitle(self, subtitle): if self.master.subtitles: drawSubtitle = self.eI.getGlobal("drawSubtitle") subtitlesFile = open( DIALOG_PATH + self.master.language + "/" + "dialogs" + TEXT_EXT, "r") self.currentSubtitle = subtitle try: subtitles = eval(subtitlesFile.read()) drawSubtitle(subtitles[subtitle]) except: self.oP("Failed to read subtitles.") drawSubtitle(subtitle) subtitlesFile.close() def clearSubtitle(self): clearSubtitle = self.eI.getGlobal("clearSubtitle") clearSubtitle()
def __init__(self, master): self.oP = OutPipe("SubtitleDrawer", 0) self.eI = EngineInterface() self.master = master self.currentSubtitle = None self.oP("Initialized.")
def __init__(self): self.oP = OutPipe("ShaderHandler", 0) self.eI = EngineInterface() self.actionQueue = [] self.actionCooldown = 0 self.oldObjectCount = 0 self.oP("Initialized.")
def __init__(self): #Socket self.__s = None #Queues self.__sq = [] self.__rq = [] #Incremental IDs self.__packetIDOut = -1 #Clients self.clients = [] #Acknowledgements self.__requiredAcks = {} #Shutdown self.killThread = False self.killQueue = [] #Logging self.NAME = "" self.DEBUG = False self.VERBOSE = False self.DATADUMP = False #Network self.BUFFER = 1024 self.HOST = "0.0.0.0" self.PORT = 7777 #Config self.PROTO = "" self.DUPLEX = True self.FORCESEND = False self.FORCERECV = False #Blocking/Timeout self.BLOCK = 0 self.TIMEOUT = 0.001 #FIXME REMOVE FOR RE-USE self.eI = EngineInterface() self.pingcount = 1 self.pr("Started NetCore.")
class Localizer(): def __init__(self, master): self.oP = OutPipe("Localizer", 0) self.eI = EngineInterface() self.master = master self.oldLanguage = "" self.oldObjectCount = 0 self.oP("Initialized.") def getLocalization(self, msg): localizationFile = open(LOCALIZATION_PATH+self.master.get("cl_language")+"/"+"strings"+TEXT_EXT, "r") try: strings = eval(localizationFile.read()) return strings[msg] except: return msg def loop(self): if self.oldLanguage != self.master.get("cl_language"): for obj in self.eI.getAllObjects(): if "localized" in obj: localized = self.getLocalization(obj["localized"]) if obj["Text"] != localized: obj["Text"] = localized self.oldLanguage = self.master.get("cl_language") objects = self.eI.getAllObjects() if self.oldObjectCount != len(objects): for obj in objects: if hasattr(obj, "resolution"): obj.resolution = 10 if "localized" in obj and obj["Text"] in ["", "Text", obj["localized"]]: localized = self.getLocalization(obj["localized"]) if obj["Text"] != localized: obj["Text"] = localized self.oldObjectCount = len(objects)
def __init__(self): #Remove engine log try: os.remove(ENGINE_PATH + "engine_log" + TEXT_EXT) except: pass #Remove net logs try: for i in os.listdir(NET_PATH): os.remove(NET_PATH + i) except: pass #Create net path try: os.mkdir(NET_PATH) except: pass self.oP = OutPipe("Launcher", 0) for line in self.getSystemInfo(): self.oP(line) self.cR = ConfigReader(ENGINE_PATH + "engine") self.sE = ScriptExecuter() self.eI = EngineInterface() self.eI.preLoad() self.eI.preLoadEpi() #Sloppy, removes the blacker that covers up starting glitches self.eI.getOverlayScene().objects["BlackScreen"].endObject() self.sound = SoundEngine() self.sound.preLoadAudio() self.s = None self.c = None self.output = True self.oP("Initialized.")
class SoundEngine(): def __init__(self): self.oP = OutPipe("SoundEngine", 0) self.eI = EngineInterface() self.sD = SubtitleDrawer(self) self.subtitles = 1 self.language = "en" self.device = aud.device() self.sounds = {} self.dialogs = {} self.music = None self.musicHandle = None self.playbacks = [] self.dialogPlaybacks = [] self.videoAudio = None self.masterVolume = 1.0 self.dialogVolume = 1.0 self.musicVolume = 1.0 self.soundVolume = 1.0 self.setMasterVolume(1.0) self.oP("Initialized.") def preLoadAudio(self): self.oP("Preloading audio files...") f = open(GAME_PATH + "preload_audio" + TEXT_EXT, "r") try: data = eval(f.read()) except: pass f.close() for i in data: if i[1] == "sound": self.loadSound(i[0]) if i[1] == "music": self.loadSound(i[0], music=True) if i[1] == "dialog": self.loadSound(i[0], dialog=True) def setMasterVolume(self, volume): self.masterVolume = volume * 0.1 self.device.volume = self.masterVolume def setDialogVolume(self, volume): self.dialogVolume = volume * 0.1 for key in self.dialogs.keys(): self.sounds[key].volume = self.soundVolume for i in self.dialogPlaybacks: i.volume = self.soundVolume def setMusicVolume(self, volume): self.musicVolume = volume * 0.1 if self.music: self.music.volume = self.musicVolume if self.musicHandle: self.musicHandle.volume = self.musicVolume def setSoundVolume(self, volume): self.soundVolume = volume * 0.1 for key in self.sounds.keys(): self.sounds[key].volume = self.soundVolume for i in self.playbacks: i.volume = self.soundVolume def loop(self): self.listener = self.eI.getMainScene().active_camera self.device.listener_location = self.listener.worldPosition self.device.listener_orientation = self.listener.worldOrientation.to_quaternion( ) self.device.listener_velocity = self.listener.getLinearVelocity() #Update 3D positioning for playback in self.playbacks + self.dialogPlaybacks: if playback[1].status == True: if playback[0]: playback[1].relative = False playback[1].location = playback[0].worldPosition playback[1].orientation = playback[ 0].worldOrientation.to_quaternion() playback[1].velocity = playback[0].getLinearVelocity() else: playback[1].relative = False playback[1].location = self.listener.worldPosition playback[ 1].orientation = self.listener.worldOrientation.to_quaternion( ) playback[1].velocity = self.listener.getLinearVelocity() #Garbage collection else: if playback in self.playbacks: self.playbacks.remove(playback) break #Clear subtitles for playback in self.dialogPlaybacks: if playback[1].status == False: if self.sD.currentSubtitle == playback[2]: self.sD.clearSubtitle() self.dialogPlaybacks.remove(playback) break #Music positioning and garbage collection if self.musicHandle and self.musicHandle.status == True: self.musicHandle.relative = False self.musicHandle.location = self.listener.worldPosition self.musicHandle.orientation = self.listener.worldOrientation.to_quaternion( ) self.musicHandle.velocity = self.listener.getLinearVelocity() elif self.musicHandle and self.musicHandle.status == False: self.musicHandle = None def load(self, location, name): path = LOCATIONS[location] if "Dialog" in path: path += self.language + "/" cR = ContentReader(path + name) return cR def loadSound(self, sound, music=False, dialog=False): if dialog: cR = self.load("Dialog", sound) EXT = DIALOG_EXT PATH = DIALOG_PATH + self.language + "/" elif not music: cR = self.load("Sound", sound) EXT = SOUND_EXT PATH = SOUND_PATH else: cR = self.load("Music", sound) EXT = MUSIC_EXT PATH = MUSIC_PATH name = cR.get("name") volume = cR.get("volume") loop = cR.get("loop") sound3D = cR.get("3D") resourceNames = cR.get("resources") resources = [] for n in resourceNames: try: factory = aud.Factory.file(PATH + n + EXT) #Configure specific volumes if dialog: factory = factory.volume(self.dialogVolume) elif not music: factory = factory.volume(self.soundVolume) else: factory = factory.volume(self.musicVolume) if loop: factory = factory.loop(-1) resources.append(factory) self.oP("Loaded sound resource %s." % (n + EXT)) except: self.oP("Failed to load sound resource %s." % (n + EXT)) self.oP("Loaded sound %s." % sound) if dialog: self.dialogs[name] = Sound(self, name, sound3D, resources) elif not music: self.sounds[name] = Sound(self, name, sound3D, resources) else: self.music = Sound(self, name, sound3D, resources) def playSound(self, sound, emitter=None): if not sound in self.sounds: self.loadSound(sound) if sound in self.sounds: soundObject = self.sounds[sound] handle = soundObject.play() self.playbacks.append([emitter, handle, sound]) return handle def stopSound(self, handle): handle.stop() for playback in self.playbacks: if playback[1] == handle: self.playbacks.remove(playback) return playback[0].GUID, playback[2] def playDialog(self, dialog, emitter=None): if not dialog in self.dialogs: self.loadSound(dialog, dialog=True) if dialog in self.dialogs: dialogObject = self.dialogs[dialog] handle = dialogObject.play() self.dialogPlaybacks.append([emitter, handle, dialog]) self.sD.drawSubtitle(dialog) return handle def stopDialog(self, handle): handle.stop() for playback in self.dialogPlaybacks: if playback[1] == handle: self.dialogPlaybacks.remove(playback) return playback[0].GUID, playback[2] def stopSoundByGUID(self, GUID, name): for playback in self.playbacks: if playback[0]["GUID"] == GUID and playback[2] == name: playback[1].stop() self.playbacks.remove(playback) def playMusic(self, music): if self.music: self.stopMusic() self.loadSound(music, music=True) self.musicHandle = self.music.play() self.oP("Started music %s." % music) def stopMusic(self): if self.music: self.music.stop() self.music = None self.oP("Stopped music.") def playVideoAudio(self, name): resource = aud.Factory.file(VIDEO_PATH + name + SOUND_EXT) resource = resource.volume(self.soundVolume) try: self.videoAudio = self.device.play(resource, False) except: pass def stopVideoAudio(self): if self.videoAudio: self.videoAudio.stop() self.videoAudio = None self.oP("Stopped video audio.")
class ShaderHandler(): def __init__(self): self.oP = OutPipe("ShaderHandler", 0) self.eI = EngineInterface() self.actionQueue = [] self.actionCooldown = 0 self.oldObjectCount = 0 self.oP("Initialized.") def enableShader(self, index, name, mode): self.actionQueue.append(["enable", index, name, mode]) def disableShader(self, index): self.actionQueue.append(["disable", index]) def doShaderAction(self): if not self.actionQueue: return action = self.actionQueue.pop() if action[0] == "enable": index = action[1] name = action[2] mode = action[3] launcher = self.eI.getGlobal("launcher") text = "" if mode == "fragment": fsh = open(SHADER_PATH + name + FSHADER_EXT, "r") text = fsh.read() fsh.close() elif mode == "vertex": vsh = open(SHADER_PATH + name + VSHADER_EXT, "r") text = vsh.read() vsh.close() else: return launcher.enableShader(index, text) elif action[0] == "disable": index = action[1] launcher = self.eI.getGlobal("launcher") launcher.disableShader(index) self.actionCooldown = 120 def loop(self): objects = self.eI.getAllObjects() if self.oldObjectCount != len(objects): for obj in objects: if "shader" in obj and not "shaderLoaded" in obj: fsh = open(SHADER_PATH + obj["shader"] + FSHADER_EXT, "r") fShaderText = fsh.read() fsh.close() vsh = open(SHADER_PATH + obj["shader"] + VSHADER_EXT, "r") vShaderText = vsh.read() vsh.close() mesh = obj.meshes[0] for mat in mesh.materials: shader = mat.getShader() if shader != None and not shader.isValid(): shader.setSource(vShaderText, fShaderText, 1) obj["shaderLoaded"] = True self.oldObjectCount = len(objects) if self.actionCooldown > 0: self.actionCooldown -= 1 else: self.doShaderAction()
from engineinterface import EngineInterface from tools import * eI = EngineInterface() def csp_look(command): client = eI.getGlobal("client") if client: cameraObj = eI.getMainScene().active_camera if "GUID" in cameraObj: camera = client.getEntityByGUID(cameraObj["GUID"]) if camera and camera.name == "playercamera": player = client.getEntityByGUID( eI.getTerminalParent(cameraObj)["GUID"]) #client.addToRotationBlacklist(player.GUID) Input.csp_look = csp_look
def __init__(self): self.oP = OutPipe("VideoPlayer", 0) self.eI = EngineInterface() self.oP("Initialized.")
class Server(GameSide): def __init__(self): '''Initializes the server.''' self.mode = "server" self.oP = OutPipe("Server", 0) self.nC = None self.cvars = { "sv_addr": "0.0.0.0", "sv_port": 7777, "sv_netlog": 0, "sv_level": "", "sv_game": 0, "sv_singleplayer": 0, "sv_gamemode": "singleplayer", "sv_startscript": "", "sv_master": "", "sv_dedicated": 0, "sv_chat": 1, "sv_background_red": 0, "sv_background_green": 0, "sv_background_blue": 0, "sv_background_alpha": 0, "sv_password": "", "cl_language": "en", "cl_subtitles": 1, "cl_width": 1280, "cl_height": 720, "cl_fullscreen": 0, "cl_motionblur": 0, "cl_motionblur_amount": 0, "cl_anisotropic": 1, "cl_mipmap": "none", "cl_vsync": "off", "cl_musicvolume": 10, "cl_dialogvolume": 10, "cl_soundvolume": 10, "cl_netping": 0, } self.netVars = {} self.oldNetVars = self.netVars self.oldcvars = self.cvars self.gameMode = None self.level = None self.unassignedPlayers = [] self.entities = [] self.events = [] self.saveFile = None self.chatMessages = [] self.eI = EngineInterface(True) self.sE = ScriptExecuter() self.pR = PhysicsReader(self) self.sH = ShaderHandler() self.l = Localizer(self) self.updateNetwork() self.forceUpdateCVars() self.keepAliveTicker = 0 self.trackedProperties = [] loadServer(self) self.oP("Initialized.") def forceUpdateCVars(self): '''Forces all the cVars to run their updaters as though they had just been set.''' for key in self.cvars.keys(): if not "cl_" == key[:3]: self.configure(key, self.get(key), override=True) self.oP("Force updated cVars.") def configureNetVar(self, var, val): '''Configures a NetVar and updates clients about it.''' self.netVars[var] = val self.events.append([None, ["SYSTEM", "NETVARS", [var, val]]]) self.oP("Configured netVar %s to %s." % (str(var), str(val))) def configure(self, key, val, override=False): '''Configure a cvar.''' changed = False if key in self.cvars.keys(): #Switch for int if type(self.cvars[key]) == type(0): val = int(val) #Used for functions if type(self.cvars[key]) == type(self.configure): self.cvars[key](val) self.oP("CVar %s executed." % key) else: if val != self.cvars[key] or override: changed = True self.cvars[key] = val self.sendEvent([None, ["SYSTEM", "CVARS", [key, val]]]) self.oP("CVar %s configured to %s (%s)." % (key, val, str(type(val)).replace( "<class '", "").replace("'>", ""))) else: self.oP("CVar %s not present." % key) if changed: self.updateGame(key) def endGame(self): '''Ends the game instance.''' self.oP("Ending game instance.") self.endGameMode() self.endLevel() def endGameMode(self): '''Ends the game mode.''' if hasattr(self.gameMode, "kill"): self.gameMode.kill() self.gameMode = None def replaceMesh(self, ent, meshName): '''Replaces the mesh of an entity.''' cR = self.load("Mesh", meshName) name = cR.get("name") resourcePath = cR.get("resourcePath") self.loadLibrary("Mesh", resourcePath, mesh=True) for obj in self.eI.getMainScene().objectsInactive: if obj.name == meshName: meshName = obj.meshes[0] break ent.gameObject.replaceMesh(meshName, True, True) self.sendEvent([None, ["PHYSICS", "MESH", [ent.GUID, meshName]]]) self.oP("Replaced mesh of %s with %s." % (ent.GUID, meshName)) def quitGame(self): '''Ends the game and kills network connections.''' self.oP("Shutting down...") self.endGame() self.purgeNetwork() def setGameMode(self, name): '''Load a gamemode into the engine.''' self.sE.addContext("Server", self) self.sE.execute(GAMEMODE_PATH + name) self.gameMode = self.newGamemode(self) def updateNetwork(self): '''Update the network module for changes to port or addr''' self.purgeNetwork() self.nC = NetCore() if self.get("sv_netlog"): self.nC.configure("DEBUG", True) self.nC.configure("VERBOSE", True) else: self.nC.configure("DEBUG", False) self.nC.configure("VERBOSE", False) self.nC.pingcount = self.get("cl_netping") self.nC.configure("NAME", "Server") self.nC.setProtocol("UDP") self.nC.configure("HOST", self.get("sv_addr")) self.nC.configure("PORT", self.get("sv_port")) self.nC.initialize() def purgeNetwork(self): '''Destroys the NetCore once and for all.''' if self.nC: self.nC.clear() self.nC.destroy() self.nC = None def setMusic(self, music): '''Sets the music track.''' launcher = self.eI.getGlobal("launcher") launcher.sound.playMusic(music) self.events.append([None, ["SYSTEM", "MUSIC_PLAY", [music, 0.0]]]) self.oP("Set music to %s." % music) def stopMusic(self): '''Stops the music track.''' launcher = self.eI.getGlobal("launcher") launcher.sound.stopMusic() self.events.append([None, ["SYSTEM", "MUSIC_STOP", None]]) def playSound(self, sound, emitter=None): '''Plays a sound.''' launcher = self.eI.getGlobal("launcher") if emitter: launcher.sound.playSound(sound, emitter.gameObject) self.events.append( [None, ["SYSTEM", "SOUND_PLAY", [emitter.GUID, sound]]]) else: launcher.sound.playSound(sound) self.events.append([None, ["SYSTEM", "SOUND_PLAY", [None, sound]]]) self.oP("Started sound %s." % sound) def stopSound(self, handle): '''Stops a sound.''' launcher = self.eI.getGlobal("launcher") GUID, sound = launcher.sound.stopSound(handle) self.events.append(["SYSTEM", "SOUND_STOP", [emitter.GUID, sound]]) self.oP("Stopped sound %s." % sound) def stopSoundByGUID(self, GUID, name): '''Stops a sound.''' launcher = self.eI.getGlobal("launcher") GUID, sound = launcher.sound.stopSoundByGUID(GUID, name) self.oP("Stopped sound %s." % sound) self.events.append(["SYSTEM", "SOUND_STOP", [emitter.GUID, sound]]) self.oP("Stopped sound %s." % sound) def playDialog(self, sound, emitter=None): '''Plays a dialog line.''' launcher = self.eI.getGlobal("launcher") if emitter: launcher.sound.playDialog(sound, emitter.gameObject) self.events.append( [None, ["SYSTEM", "DIALOG_PLAY", [emitter.GUID, sound]]]) else: launcher.sound.playDialog(sound) self.events.append( [None, ["SYSTEM", "DIALOG_PLAY", [None, sound]]]) self.oP("Started dialog %s." % sound) def stopDialog(self, handle): '''Stops a dialog line.''' launcher = self.eI.getGlobal("launcher") GUID, sound = launcher.sound.stopDialog(handle) self.events.append(["SYSTEM", "DIALOG_STOP", [emitter.GUID, sound]]) self.oP("Stopped dialog %s." % sound) def stopDialogByGUID(self, GUID, name): '''Stops a dialog line.''' launcher = self.eI.getGlobal("launcher") GUID, sound = launcher.sound.stopDialogByGUID(GUID, name) self.oP("Stopped dialog %s." % sound) self.events.append(["SYSTEM", "DIALOG_STOP", [emitter.GUID, sound]]) self.oP("Stopped dialog %s." % sound) def enableShader(self, index, name, mode): '''Enables a shader as a filter for the entire screen.''' self.sH.enableShader(index, name, mode) def disableShader(self, index): '''Disables a shader that was filtering the entire screen.''' self.sH.disableShader(index) def updateGame(self, key): '''Reacts to changes to the cVars.''' if key == "sv_gamemode" and self.get("sv_game"): self.setGameMode(self.get("sv_gamemode")) elif key == "sv_level" and self.get("sv_game"): self.configure("sv_game", 0) self.configure("sv_game", 1) elif key == "sv_game": if self.get("sv_game"): self.setGameMode(self.get("sv_gamemode")) self.setLevel(self.get("sv_level")) else: self.endGame() elif key == "sv_port" or key == "sv_addr": self.updateNetwork() elif key == "sv_startscript": self.sE.addContext("Server", self) self.sE.execute(self.get("sv_startscript")) elif key in [ "sv_background_red", "sv_background_green", "sv_background_blue", "sv_background_alpha" ] and not self.get("cl_master"): self.eI.setBackgroundColor((self.getBackgroundColor())) elif key == "sv_netlog": if self.get("sv_netlog"): self.nC.configure("DEBUG", True) self.nC.configure("VERBOSE", True) else: self.nC.configure("DEBUG", False) self.nC.configure("VERBOSE", False) elif key == "cl_width" or key == "cl_height": self.eI.setResolution(self.get("cl_width"), self.get("cl_height")) elif key == "cl_fullscreen": self.eI.setFullscreen(self.get("cl_fullscreen")) elif key == "cl_motionblur" or key == "cl_motionblur_amount": self.eI.setMotionBlur(self.get("cl_motionblur"), self.get("cl_motionblur_amount")) elif key == "cl_anisotropic": self.eI.setAnisotropic(self.get("cl_anisotropic")) elif key == "cl_mipmap": self.eI.setMipmapping(self.get("cl_mipmap")) elif key == "cl_vsync": self.eI.setVSync(self.get("cl_vsync")) elif key == "cl_mastervolume": launcher = self.eI.getGlobal("launcher") if launcher: launcher.sound.setMasterVolume(self.get("cl_mastervolume")) elif key == "cl_musicvolume": launcher = self.eI.getGlobal("launcher") if launcher: launcher.sound.setMusicVolume(self.get("cl_musicvolume")) elif key == "cl_dialogvolume": launcher = self.eI.getGlobal("launcher") if launcher: launcher.sound.setDialogVolume(self.get("cl_dialogvolume")) elif key == "cl_soundvolume": launcher = self.eI.getGlobal("launcher") if launcher: launcher.sound.setSoundVolume(self.get("cl_soundvolume")) elif key == "cl_subtitles": launcher = self.eI.getGlobal("launcher") if launcher: launcher.sound.subtitles = self.get("cl_subtitles") elif key == "cl_language": launcher = self.eI.getGlobal("launcher") if launcher: launcher.sound.language = self.get("cl_language") elif key == "cl_netping": self.nC.pingcount = self.get("cl_netping") def getEmergencyUpdate(self, cli): '''Gets a special update to repair desynced clients.''' events = [] for var in self.cvars: if not "cl_" == var[:3]: events.append( [cli, ["SYSTEM", "CVARS", [var, self.cvars[var]]]]) for var in self.netVars: events.append( [cli, ["SYSTEM", "NETVARS", [var, self.netVars[var]]]]) return events def setPlayerCamera(self, cli, GUID): '''Set a client's current camera.''' self.events.append([cli, ["SYSTEM", "SET_CAMERA", GUID]]) if cli: self.oP("Set client %s camera to be %s" % (str(cli.addr), GUID)) else: self.oP("Set all client cameras to be %s" % GUID) def checkServer(self): '''Runs server loops and checks for events.''' events = [] #CVar based events for key in self.cvars.keys(): if not key in self.oldcvars or self.cvars[key] != self.oldcvars[ key]: events.append(["SYSTEM", "CVARS", [key, self.cvars[key]]]) self.oldcvars = self.cvars if self.gameMode: self.gameMode.loop() #Other game events events += self.events self.events = [] return events def sendChatMessage(self, msg, client=None): '''Sends a chat message to the client(s).''' self.sendEvent([client, ["SYSTEM", "CHAT", msg]]) self.chatMessages.append(msg) def sendEvent(self, event): '''Sends an event to the client(s).''' if (event[1][0] == "PHYSICS" and not event[1][1] in ["CREATE", "DELETE"]) or event[1] == "KEEPALIVE": mode = "FAF" else: mode = "RT" #Send global events if event[0] == None: for cli in self.nC.clients: if cli.userProps["confirmed"] or not self.get("sv_password"): cli.send(event[1], mode) #Send one user events else: if event[0].userProps["confirmed"] or not self.get("sv_password"): event[0].send(event[1], mode) def recvEvent(self, cli, event): '''Handles an event from a client.''' if type(event) == type([]) and len(event) >= 3: if event[0] == "INPUT": if event[1] == "COMMAND" or event[1] == "INTERFACE": if cli.userProps["player"]: cli.userProps["player"].pushCommand(event[2]) elif event[0] == "SYSTEM": if event[1] == "PHYSICS": if event[2] == "FORCEUPDATE" and not cli.userProps[ "synced"]: events = self.pR.getEmergencyUpdate(cli) events += self.getEmergencyUpdate(cli) for event in events: self.sendEvent(event) cli.userProps["synced"] = True elif event[1] == "CVARS": if cli.addr[0] == self.get("sv_master"): self.configure(event[2][0], event[2][1]) elif event[1] == "CHAT" and self.get("sv_chat"): self.chatMessages.append(event[2]) self.sendEvent([None, event]) elif event[1] == "NAME": if cli.userProps["player"]: cli.userProps["player"].username = event[2] cli.userProps["username"] = event[2] elif event[1] == "PASSWORD": if event[2] == self.get("sv_password"): cli.userProps["confirmed"] = True elif event[0] == "GAME": self.gameMode.pushGameEvent([event[1], event[2]]) def openSaveFile(self, name): '''Opens the save file.''' try: self.saveFile = shelve.open(SAVE_PATH + name + SAVE_EXT) self.oP("Opened save file %s." % (SAVE_PATH + name + SAVE_EXT)) return True except: self.saveFile = None self.oP("Failed to open save file %s." % (SAVE_PAT + name + SAVE_EXT)) return False def closeSaveFile(self): '''Closes the save file.''' if self.saveFile != None: self.saveFile.close() self.oP("Closed the save file.") self.saveFile = None def saveSaveFile(self): '''Saves the save file.''' if self.saveFile != None: self.oP("Saved the save file.") self.saveFile.sync() def saveState(self): '''Saves the game state.''' self.oP("Saving entity state.") self.openSaveFile("save") if self.saveFile != None: data = Sarcophagus() for ent in self.entities: #if ent.name != "avatar": self.saveEntity(ent, data) for cli in self.nC.clients: if cli.userProps["player"]: self.savePlayer(cli.userProps["player"], data) for player in self.unassignedPlayers: self.savePlayer(player, data) records, playerRecords = data.cleanUp() try: self.saveFile["data"] = data self.oP("Saved data to save file.") except: self.oP("Failed to save data to save file.") self.saveSaveFile() self.closeSaveFile() data.restore(records, playerRecords) for ent in self.entities: #if ent.name != "avatar": data.reconstructEntity(ent) for cli in self.nC.clients: if cli.userProps["player"]: data.reconstructPlayer(cli.userProps["player"]) for player in self.unassignedPlayers: data.reconstructPlayer(player) def loadState(self): '''Loads the game state.''' self.oP("Loading entity state.") self.openSaveFile("save") if self.saveFile != None: if "data" in self.saveFile.keys(): container = self.saveFile["data"] for entry in container.entities: self.loadEntity(entry) for player in container.players: self.loadPlayer(player) self.closeSaveFile() def saveEntity(self, ent, data): '''Saves an Entity to the sarcophagus.''' objData = self.pR.getObjectData(ent) data.deconstructEntity(ent) data.addEntity(ent, objData) def savePlayer(self, player, data): '''Saves a Player to the sarcophagus.''' data.deconstructPlayer(player) data.addPlayer(player) def loadEntity(self, entry): '''Reconstructs an Entity.''' ent = entry[0] ent.reconstructObject(entry[1]) self.oP("Retrieved entity %s from save file." % ent.GUID) self.entities.append(ent) def loadPlayer(self, player): '''Reconstructs a player.''' player.reconstructPlayer(self) self.oP("Retrieved player %s from save file." % player.username) self.unassignedPlayers.append(player) def getOldPlayer(self, name): '''Checks for an unassigned player.''' for player in self.unassignedPlayers: if player.username == name: return player def removeOldPlayer(self, player): '''Removes a player from the unassigned list.''' self.unassignedPlayers.remove(player) def disconnectPlayer(self, cli): '''Handles the disconnection of a player.''' if cli.userProps["player"]: cli.userProps["player"].cli = None self.unassignedPlayers.append(cli.userProps["player"]) def loop(self): '''Does everything basically.''' #cl = OptiClock() #Detector Index self.updateDetectorIndex() #cl.clockIn("DetectorIndex") #KEEP ALIVE self.keepAliveTicker += 1 if self.keepAliveTicker % 600 == 0: self.sendEvent([None, "KEEPALIVE"]) #cl.clockIn("KeepAlive") #RECV THINGS############################################### for cli in self.nC.clients: #Make sure only one client gets through on singleplayer if not self.get("sv_singleplayer") or len(self.nC.clients) <= 1: #Create a player once the username is collected if not cli.userProps["player"] and "username" in cli.userProps: player = self.getOldPlayer(cli.userProps["username"]) if player: self.oP("Client's previous avatar found, reassigning.") cli.userProps["player"] = player player.cli = cli player.reLinkPlayer() self.removeOldPlayer(cli.userProps["player"]) else: self.oP("Client gets a new avatar.") cli.userProps["player"] = Player(self, cli) cli.disconnectFunc = cli.userProps["player"].destruct #If a player has been created elif cli.userProps["player"]: cli.userProps["player"].loop() packet = cli.recv() if packet: payload = packet.getPayload() try: data = eval(payload) except: data = None if data: self.recvEvent(cli, data) #cl.clockIn("RecvLoop") #CHANGE THINGS########################################### #Apply Shaders self.sH.loop() #cl.clockIn("Shaders") #Localize text self.l.loop() #cl.clockIn("Localization") #Entities loop for ent in self.entities: ent.checkPhysics() ent.checkAnimation() if hasattr(ent, "loop"): #print(ent) ent.loop(self, "server") #cl.clockIn("Entities") #Physics Read Loop events = self.pR.loop() #cl.clockIn("Physics") #Self Read Loop events += self.checkServer() #cl.clockIn("GameEvents") #Gamerules Loop if hasattr(self.gameMode, "loop"): self.gameMode.loop() #cl.clockIn("GameMode") #Level loop if self.level and hasattr(self.level, "loop"): self.level.loop(self, "server") #cl.clockIn("Level") #SEND THINGS############################################### #Send Events for event in events: self.sendEvent(event) #cl.clockIn("SendLoop") #KILL THINGS################################################### kill = self.nC.pullKillQueue() if kill and self.gameMode: kill() #cl.clockIn("Kill") self.nC.loop()
class Launcher(): def __init__(self): #Remove engine log try: os.remove(ENGINE_PATH + "engine_log" + TEXT_EXT) except: pass #Remove net logs try: for i in os.listdir(NET_PATH): os.remove(NET_PATH + i) except: pass #Create net path try: os.mkdir(NET_PATH) except: pass self.oP = OutPipe("Launcher", 0) for line in self.getSystemInfo(): self.oP(line) self.cR = ConfigReader(ENGINE_PATH + "engine") self.sE = ScriptExecuter() self.eI = EngineInterface() self.eI.preLoad() self.eI.preLoadEpi() #Sloppy, removes the blacker that covers up starting glitches self.eI.getOverlayScene().objects["BlackScreen"].endObject() self.sound = SoundEngine() self.sound.preLoadAudio() self.s = None self.c = None self.output = True self.oP("Initialized.") def enableShader(self, index, text): self.oP("Activating shader pass #%i" % index) controller = bge.logic.getCurrentController() filterActuator = controller.actuators["filter"] filterActuator.mode = bge.logic.RAS_2DFILTER_CUSTOMFILTER filterActuator.passNumber = index filterActuator.shaderText = text controller.activate(filterActuator) controller.deactivate(filterActuator) def disableShader(self, index): self.oP("Deactivating shader pass #%i" % index) controller = bge.logic.getCurrentController() filterActuator = controller.actuators["filter"] filterActuator.mode = bge.logic.RAS_2DFILTER_DISABLED filterActuator.passNumber = index controller.activate(filterActuator) controller.deactivate(filterActuator) def bootSystem(self): self.output = int(self.cR.get("LAUNCHER", "la_output")) dedicated = int(self.cR.get("LAUNCHER", "la_dedicated")) if dedicated: lobby = int(self.cR.get("LAUNCHER", "la_dedicated_fast")) self.bootServer() self.s.configure("sv_game", lobby) self.s.configure("sv_dedicated", 1) else: self.bootClient() def getSystemInfo(self): f = open(ENGINE_PATH + "system" + TEXT_EXT, "r") try: data = eval(f.read()) return [ "EpiEngine v%.2f" % data["version"], "Built for BGE %.2f" % data["targetVersion"], "Running %s %.2f" % (data["game"], data["gameVersion"]), "Built %s" % data["date"], ] except: return "EpiEngine launching." f.close() def bootClient(self): self.c = Client() #self.sE.addContext("Client", self.c) #self.sE.execute(bootScript) for option in self.cR.getAllOptions("CLIENT"): self.c.configure(option, self.cR.get("CLIENT", option)) def bootServer(self): #bootScript = self.cR.get("SERVER", "sv_startscript") #addr = self.cR.get("SERVER", "sv_addr") #port = self.cR.get("SERVER", "sv_port") self.s = Server() #self.sE.addContext("Server", self.s) #self.sE.execute(bootScript) # #self.s.configure("sv_addr", addr) #self.s.configure("sv_port", int(port)) for option in self.cR.getAllOptions("SERVER"): self.s.configure(option, self.cR.get("SERVER", option)) def configureServer(self, level, gamemode): if self.s: self.s.configure("level", level) self.s.configure("gamemode", gamemode) def loop(self): self.sound.loop() try: if hasattr(self.c, "loop"): self.c.loop() except: self.oP("Failure in client loop: %s" % str(traceback.format_exc())) try: if hasattr(self.s, "loop"): self.s.loop() except: self.oP("Failure in server loop: %s" % str(traceback.format_exc())) def pushConsoleCommand(self, command): if hasattr(self, "s") and self.s: self.s.pushConsoleCommand(command) if hasattr(self, "c") and self.c: self.c.pushConsoleCommand(command)
def __init__(self): '''Initializes the server.''' self.mode = "server" self.oP = OutPipe("Server", 0) self.nC = None self.cvars = { "sv_addr": "0.0.0.0", "sv_port": 7777, "sv_netlog": 0, "sv_level": "", "sv_game": 0, "sv_singleplayer": 0, "sv_gamemode": "singleplayer", "sv_startscript": "", "sv_master": "", "sv_dedicated": 0, "sv_chat": 1, "sv_background_red": 0, "sv_background_green": 0, "sv_background_blue": 0, "sv_background_alpha": 0, "sv_password": "", "cl_language": "en", "cl_subtitles": 1, "cl_width": 1280, "cl_height": 720, "cl_fullscreen": 0, "cl_motionblur": 0, "cl_motionblur_amount": 0, "cl_anisotropic": 1, "cl_mipmap": "none", "cl_vsync": "off", "cl_musicvolume": 10, "cl_dialogvolume": 10, "cl_soundvolume": 10, "cl_netping": 0, } self.netVars = {} self.oldNetVars = self.netVars self.oldcvars = self.cvars self.gameMode = None self.level = None self.unassignedPlayers = [] self.entities = [] self.events = [] self.saveFile = None self.chatMessages = [] self.eI = EngineInterface(True) self.sE = ScriptExecuter() self.pR = PhysicsReader(self) self.sH = ShaderHandler() self.l = Localizer(self) self.updateNetwork() self.forceUpdateCVars() self.keepAliveTicker = 0 self.trackedProperties = [] loadServer(self) self.oP("Initialized.")
class TypingHandler(): def __init__(self, keyboard): self.oP = OutPipe("TypingHandler", 0) self.eI = EngineInterface() self.keyboard = keyboard self.letters = { self.eI.e.AKEY: "a", self.eI.e.BKEY: "b", self.eI.e.CKEY: "c", self.eI.e.DKEY: "d", self.eI.e.EKEY: "e", self.eI.e.FKEY: "f", self.eI.e.GKEY: "g", self.eI.e.HKEY: "h", self.eI.e.IKEY: "i", self.eI.e.JKEY: "j", self.eI.e.KKEY: "k", self.eI.e.LKEY: "l", self.eI.e.MKEY: "m", self.eI.e.NKEY: "n", self.eI.e.OKEY: "o", self.eI.e.PKEY: "p", self.eI.e.QKEY: "q", self.eI.e.RKEY: "r", self.eI.e.SKEY: "s", self.eI.e.TKEY: "t", self.eI.e.UKEY: "u", self.eI.e.VKEY: "v", self.eI.e.WKEY: "w", self.eI.e.XKEY: "x", self.eI.e.YKEY: "y", self.eI.e.ZKEY: "z", } self.specials = { self.eI.e.ZEROKEY: "0", self.eI.e.ONEKEY: "1", self.eI.e.TWOKEY: "2", self.eI.e.THREEKEY: "3", self.eI.e.FOURKEY: "4", self.eI.e.FIVEKEY: "5", self.eI.e.SIXKEY: "6", self.eI.e.SEVENKEY: "7", self.eI.e.EIGHTKEY: "8", self.eI.e.NINEKEY: "9", self.eI.e.ACCENTGRAVEKEY: "`", self.eI.e.BACKSLASHKEY: "\\", self.eI.e.COMMAKEY: ",", self.eI.e.EQUALKEY: "=", self.eI.e.LEFTBRACKETKEY: "[", self.eI.e.MINUSKEY: "-", self.eI.e.PERIODKEY: ".", self.eI.e.QUOTEKEY: "'", self.eI.e.RIGHTBRACKETKEY: "]", self.eI.e.SEMICOLONKEY: ";", self.eI.e.SLASHKEY: "/", self.eI.e.SPACEKEY: " ", } self.oP("Initialized.") def process(self): scene = self.eI.getOverlayScene() for obj in scene.objects: if "Text" in obj and "TextEntry" in obj: if obj["TextEntry"]: self.enterText(obj) def enterText(self, obj): oldText = obj["Text"] newText = oldText for keycode in self.keyboard.active_events.keys(): if self.keyboard.active_events[ keycode] == self.eI.l.KX_INPUT_JUST_ACTIVATED: if keycode in self.letters.keys(): letter = self.letters[keycode] if self.caps(): letter = letter.upper() newText += letter elif keycode in self.specials.keys(): letter = self.specials[keycode] newText += letter elif keycode == self.eI.e.BACKSPACEKEY: newText = newText[:len(newText) - 1] obj["Text"] = newText def caps(self): return self.eI.e.RIGHTSHIFTKEY in self.keyboard.active_events.keys( ) or self.eI.e.LEFTSHIFTKEY in self.keyboard.active_events.keys( ) or self.eI.e.CAPSLOCKKEY in self.keyboard.active_events.keys()
def __init__(self): '''Initializes the client.''' self.mode = "client" self.oP = OutPipe("Client", 0) self.eI = EngineInterface(objectMode=True) self.vP = VideoPlayer() self.sE = ScriptExecuter() self.iR = InputReceiver() self.l = Localizer(self) self.pA = PhysicsApplicator(self) self.sH = ShaderHandler() self.nC = None self.sE.addContext("Client", self) self.cvars = { #Low level settings "cl_update": 1, "cl_synced": 0, "cl_addr": "0.0.0.0", "cl_oport": 7777, "cl_iport": 7778, "cl_netlog": 0, "cl_game": 0, "cl_startscript": "", "cl_master": 0, "cl_predict": 1, "cl_smooth": 0, "cl_name": "Player", "cl_password": "", "cl_camera": "", "cl_lockcontrols": 1, "cl_showmouse": 1, "cl_xsens": 50, "cl_ysens": 50, "cl_inverted": 0, "cl_netping": 0, #High level settings "cl_language": "en", "cl_subtitles": 1, "cl_width": 1280, "cl_height": 720, "cl_fullscreen": 0, "cl_motionblur": 0, "cl_motionblur_amount": 0, "cl_anisotropic": 1, "cl_mipmap": "none", "cl_vsync": "off", "cl_musicvolume": 10, "cl_dialogvolume": 10, "cl_soundvolume": 10, "cl_mastervolume": 10, #Server shared settings "sv_level": "", "sv_gamemode": "", "sv_game": 0, "sv_background_red": 0, "sv_background_green": 0, "sv_background_blue": 0, "sv_background_alpha": 0, } self.netVars = {} self.chatMessages = [] self.interfaces = [] self.entities = [] self.level = None self.gameEvents = [] self.updateNetwork() #self.startLoop() self.forceUpdateCVars() self.keepAliveTicker = 0 self.trackedProperties = [] loadClient(self) self.oP("Initialized.")
class NetCore(): def __init__(self): #Socket self.__s = None #Queues self.__sq = [] self.__rq = [] #Incremental IDs self.__packetIDOut = -1 #Clients self.clients = [] #Acknowledgements self.__requiredAcks = {} #Shutdown self.killThread = False self.killQueue = [] #Logging self.NAME = "" self.DEBUG = False self.VERBOSE = False self.DATADUMP = False #Network self.BUFFER = 1024 self.HOST = "0.0.0.0" self.PORT = 7777 #Config self.PROTO = "" self.DUPLEX = True self.FORCESEND = False self.FORCERECV = False #Blocking/Timeout self.BLOCK = 0 self.TIMEOUT = 0.001 #FIXME REMOVE FOR RE-USE self.eI = EngineInterface() self.pingcount = 1 self.pr("Started NetCore.") def configure(self, name, value): '''Changes a configuration property of the NetCore.''' if type(name) == type("") and hasattr(self, name): setattr(self, name, value) self.pr("%s configured to %s." % (name, str(value))) return True self.pr("Configuration failed.") return False def setProtocol(self, proto): '''Sets the protocol used to a particular protocol.''' self.pr("Setting protocol...") if type(proto) == type(""): if proto.lower() == "udp": self.PROTO = SOCK_DGRAM self.pr("Protocol set successful.") return True elif proto.lower() == "tcp": self.PROTO = SOCK_STREAM self.pr("Protocol set successful.") return True self.pr("Protocol set failed.") return False def clear(self): '''Resets the NetCore and shuts down the network.''' if self.__s: self.__s.close() self.__s = None self.__sq = [] self.__rq = [] self.clients = [] self.__packetIDOut = -1 self.__packetIDIn = -1 self.__requiredAcks = {} self.killQueue = [] self.pr("Purged system.") def destroy(self): '''Exits the NetCore thread.''' self.killThread = True self.pr("NetCore scheduled to be destroyed.") def initialize(self): '''Initializes the socket.''' self.__startSocket() self.__bind() self.__configSocket() #self.__startLoop() def pullKillQueue(self): '''Pulls a kill handler from the queue.''' if self.killQueue: i = self.killQueue[0] self.killQueue = self.killQueue[1:] return i def pushKillQueue(self, i): '''Pushs a kill callback to the queue.''' self.killQueue.append(i) def __removeClient(self, cli): '''Removes a client from the NetCore, queues it's kill callback.''' if cli.disconnectFunc: self.pushKillQueue(cli.disconnectFunc) self.clients.remove(cli) def __selectIPVersion(self): '''Gets the current IP version.''' for res in getaddrinfo(self.HOST, self.PORT, AF_UNSPEC, self.PROTO, 0, AI_PASSIVE): return res def __startSocket(self): '''Initializes the socket.''' self.pr("Initializing socket...") try: res = self.__selectIPVersion() self.__s = socket(res[0], res[1]) self.pr("Socket initialized.") return True except: self.pr("Socket initialization failed.", True) return False def __bind(self): '''Binds the socket.''' if self.DUPLEX: try: self.__s.bind((self.HOST, self.PORT)) self.pr("Bind succeeded.") return True except: self.pr("Bind failed.", True) return False else: self.pr("Bind not completed because NetCore is not set to DUPLEX.") return False def __configSocket(self): '''Configures the block and timeout properties of the socket.''' self.pr("Configuring socket...") self.__s.setblocking(self.BLOCK) self.__s.settimeout(self.TIMEOUT) self.pr("Socket configured.") def __startLoop(self): '''Starts the NetCore loop.''' self.pr("Starting loop...") t = Thread(target=self.loop, name="NetCore Loop") t.start() self.pr("Loop started.") def deconstructMultiPacket(self, packet, source): '''Takes apart a multi-packet to recover the original packets.''' packets = [] lastSplit = 0 counter = 0 skip = False for char in packet: if not skip: if char == byt("&")[0] and packet[counter + 1] == byt("&")[0]: skip = True elif char == byt("&")[0] and not packet[counter + 1] == byt("&")[0]: packetData = packet[lastSplit:counter] packets.append(Packet(packetData, source, "PACKET")) lastSplit = counter + 1 else: skip = False counter += 1 packets.append(Packet(packet[lastSplit:], source, "PACKET")) return packets def removeUsedPackets(self, mP): '''Clears out any queued packets used to make a multipacket.''' for ID in mP.ids: counter = 0 while counter < len(self.__sq): if self.__sq[counter].headers["PACKETID"] == ID: self.__sq = self.__sq[:counter] + self.__sq[counter + 1:] break counter += 1 def __recv(self): '''Socket level receipt of data.''' try: packet, source = self.__s.recvfrom(self.BUFFER) self.pr("Packet received from %s." % (str(source))) self.pr("Packet recv contents: " + str(packet), v=True) self.pr("Packet received size %i." % (len(packet)), v=True) packets = self.deconstructMultiPacket(packet, source) return packets except: #self.pr("Packet receive failed, Error: %s" % (format_exc()), v=True) return None def __send(self, packet): '''Socket level transmission of data.''' try: self.__s.sendto(packet.getPacket(), packet.addr) self.pr("Packet #%i sent to %s." % (packet.packets[0].headers["PACKETID"], str(packet.addr))) self.pr("Packet sent size %i." % (len(packet.getPacket())), v=True) self.pr((("Packet #%i sent contents: " % (packet.packets[0].headers["PACKETID"])) + str(packet.getPacket())), v=True) return True except: self.pr("Packet #%i failed to send. Error: %s" % (packet.packets[0].headers["PACKETID"], str(format_exc())), v=True) return False def loop(self): '''The main loop of the NetCore.''' #SEND while len(self.__sq) > 0: #Combine packets together mP = None if self.__sq[0].length() < self.BUFFER: destination = self.__sq[0].addr key = 0 mP = MultiPacket(self.__sq[0].addr) mP.addPacket(self.__sq[0]) for packet in self.__sq: if key != 0 and packet.addr == destination: if mP.length() + packet.length() + 1 < self.BUFFER: mP.addPacket(packet) key += 1 if mP: self.writeLog(mP, 1) self.__send(mP) self.removeUsedPackets(mP) else: self.__send(self.__sq[0]) self.__sq = self.__sq[1:] if not self.FORCESEND: break #RECV if self.DUPLEX: while 1: packets = self.__recv() if packets: for packet in packets: self.writeLog(packet, 0) self.__rq.append(packet) else: break if not self.FORCERECV: break while self.__rq: self.__processPacket(self.__rq[0]) self.__rq = self.__rq[1:] #TIMEOUT for cli in self.clients: #FIXME REMOVE FOR RE-USE if time.time( ) - cli.lastreceived > TIMEOUT_MIN and cli.lastreceived != -1: self.eI.getGlobal("drawDisconnect")( cli.addr[0], cli.addr[1], TIMEOUT - (time.time() - cli.lastreceived)) else: self.eI.getGlobal("clearDisconnect")() if time.time( ) - cli.lastreceived > TIMEOUT and cli.lastreceived != -1: self.send(Packet("", cli.addr, "PAYLOAD"), "DISCONN") try: self.__removeClient(cli) except: self.pr("Client could not be removed.") self.pr("Client %s was disconnected for inactivity." % (str(cli.addr))) self.eI.getGlobal("clearDisconnect")() #Acknowledgements for key in self.__requiredAcks.keys(): try: msg = self.__requiredAcks[key] if time.time() - msg["timesent"] > TIMEOUT_PACKET: del self.__requiredAcks[key] packet = msg["packet"] self.pr("Resending packet #%i." % key) if msg["tries"] == -1: self.__resend(packet) elif msg["tries"] > 0: self.__resend(packet, msg["tries"] - 1) break except: pass def __getNextPacketID(self): '''Gets and increments the outgoing packet ID.''' self.__packetIDOut += 1 return self.__packetIDOut def send(self, packet, mode, ack=0): '''Called by SubSockets when they need to send.''' h = {} h["PROTOID"] = 540 h["PACKETID"] = self.__getNextPacketID() if mode == "FAF": h["ACK"] = -1 h["NEEDACK"] = 0 h["CONN"] = 0 h["DISCARD"] = 1 elif mode == "RT": h["ACK"] = -1 h["NEEDACK"] = 1 h["CONN"] = 0 h["DISCARD"] = 0 elif mode == "ACK": h["ACK"] = ack h["NEEDACK"] = 0 h["CONN"] = 0 h["DISCARD"] = 0 elif mode == "CONN": h["ACK"] = -1 h["NEEDACK"] = 1 h["CONN"] = 1 h["DISCARD"] = 0 elif mode == "DISCONN": h["ACK"] = -1 h["NEEDACK"] = 2 h["CONN"] = 2 h["DISCARD"] = 0 packet.headers = h if h["NEEDACK"] == 1: self.__requiredAcks[h["PACKETID"]] = { "packet": packet, "timesent": time.time(), "tries": -1 } elif h["NEEDACK"] == 2: self.__requiredAcks[h["PACKETID"]] = { "packet": packet, "timesent": time.time(), "tries": 3 } self.__sq.append(packet) def __resend(self, packet, tries=-1): '''Queues a packet for retransmission.''' packet.headers["PACKETID"] = self.__getNextPacketID() self.__requiredAcks[packet.headers["PACKETID"]] = { "packet": packet, "timesent": time.time(), "tries": tries } self.__sq.append(packet) def __sendAcknowledgement(self, addr, packetID): if self.__sq: for packet in self.__sq: if packet.headers["ACK"] == -1: packet.headers["ACK"] = packetID break else: self.send(Packet("", addr, "PAYLOAD"), "ACK", packetID) def __processPacket(self, packet): '''Handles a received packet.''' h = packet.headers self.pr("Processing packet...", v=True) if "PROTOID" in h: self.pr("Packet headers are intact.", v=True) if h["PROTOID"] == 540: self.pr("Protocol is correct.", v=True) #Check if this packet comes from a pre-existing client done = False for cli in self.clients: if cli.addr == packet.addr: cli.lastreceived = time.time() done = True break if not done or ( (h["PACKETID"] > cli.getInPacketID() or not h["DISCARD"]) and not h["PACKETID"] in cli.receivedIDs): self.pr("Packet #%i is in order and is not a duplicate." % (h["PACKETID"]), v=True) #Client only stream security if done: if h["PACKETID"] > cli.getInPacketID(): cli.setInPacketID(h["PACKETID"]) cli.receivedIDs.append(h["PACKETID"]) #Acknowledge sendback if h["NEEDACK"]: self.pr("Packet #%i being acknowledged." % (h["PACKETID"])) self.__sendAcknowledgement(packet.addr, h["PACKETID"]) #Check for onboard acks if h["ACK"] != -1: self.pr("Packet #%i is carrying an acknowledgement." % h["PACKETID"], v=True) if h["ACK"] in self.__requiredAcks.keys(): #Connection ack if self.__requiredAcks[ h["ACK"]]["packet"].headers["CONN"] == 1: self.pr("Connection to %s acknowledged." % (str(packet.addr))) #Disconnection ack elif self.__requiredAcks[ h["ACK"]]["packet"].headers["CONN"] == 2: self.pr("Disconnection from %s acknowledged." % (str(packet.addr))) #General acks else: entry = self.__requiredAcks[h["ACK"]] #FIXME Remove for reuse if self.pingcount: self.eI.getGlobal("drawPing")( packet.addr[0], packet.addr[1], (time.time() - entry["timesent"]) * 1000) else: self.eI.getGlobal("clearPing")() del self.__requiredAcks[h["ACK"]] self.pr( "Packet #%i acknowledged on #%i accepted." % (h["ACK"], h["PACKETID"])) #Handle other packets else: #Normal Packets if h["CONN"] == 0: self.pr( "Packet #%i is normal, sending to client object." % h["PACKETID"], v=True) for cli in self.clients: if cli.addr == packet.addr: cli.pushRecv(packet) break #Connect packets elif h["CONN"] == 1: self.pr("Connect packet #%i received from %s." % (h["PACKETID"], str(packet.addr))) alreadyExists = False for cli in self.clients: if cli.addr == (packet.addr[0], int(packet.getPayload())): alreadyExists = True break if not alreadyExists: self.clients.append( SubSocket(self, (packet.addr[0], int(packet.getPayload())))) #Disconnect packets elif h["CONN"] == 2: self.pr("Disconnect packet #%i received from %s." % (h["PACKETID"], str(packet.addr))) for cli in self.clients: if cli.addr == packet.addr: self.__removeClient(cli) else: pass self.pr("Packet #%i rejected for being out of order." % h["PACKETID"], v=True) else: pass self.pr("Packet rejected for incorrect PROTOID.") else: self.pr("Packet rejected for incorrect headers.") return False def connect(self, addr): '''Attempts to connect to a remote socket.''' self.pr("Connecting to %s." % (str(addr))) self.send(Packet(str(self.PORT), addr, "PAYLOAD"), "CONN") self.clients.append(SubSocket(self, addr)) def writeLog(self, packet, direction): '''Writes statistics logging data to a file.''' if self.DATADUMP: #Open the file try: f = open( NET_PATH + "netdata_" + str(self.PORT) + "_" + self.NAME + TEXT_EXT, "a") except: f = open( NET_PATH + "netdata_" + str(self.PORT) + "_" + self.NAME + TEXT_EXT, "w") #Write the data if not hasattr(packet, "packets"): f.write("{'id':%i, 'size':%i, 'time':%.3f, 'direction':%i}\n" % (packet.headers["PACKETID"], len( packet.getPayload()), time.time(), direction)) else: for packet in packet.packets: f.write( "{'id':%i, 'size':%i, 'time':%.3f, 'direction':%i}\n" % (packet.headers["PACKETID"], len( packet.getPayload()), time.time(), direction)) #Close the file f.close() def pr(self, msg, err=False, v=False): '''Outputs to the console and/or log file.''' if self.DEBUG and (not v or self.VERBOSE): try: f = open( NET_PATH + "net_" + str(self.PORT) + "_" + self.NAME + TEXT_EXT, "ab") except: f = open( NET_PATH + "net_" + str(self.PORT) + "_" + self.NAME + TEXT_EXT, "wb") msg = "Net%s - %s - %s\n" % (self.NAME, getFormattedTime(), str(msg)) f.write(bytes(msg, "UTF-8")) f.close() if 1: print("Net%s - %s" % (self.NAME, str(msg.replace("\n", "\\n")))) if err: print(exc_info())
def initVolatileModules(self): self.eI = EngineInterface(objectMode=False) self.sE = ScriptExecuter() self.detectors = [] self.sE.addContext("Entity", self) self.sE.addContext("Detector", Detector)
class Entity(): def __init__(self, sourcename, objname, GUID, scriptName, flags, props, pos=(0,0,0), rot=(0,0,0), sca=(1,1,1), extra=None, side="SERVER"): #Tools self.oP = OutPipe("Entity - "+sourcename, 0) self.initVolatileModules() #Basic values self.name = sourcename self.GUID = "" #Extra if not extra: extra = {} #Basic Flags self.physicsTrack = False self.animTrack = False self.netVars = {} self.actions = [] self.detectors = [] self.scriptName = scriptName #Handle Flags self.processFlags(flags) #Create Object self.createObject(objname, sourcename, GUID, pos, rot, sca, props, extra) #Install custom code self.installCustomCode() if hasattr(self, "init"): self.init(side) def initVolatileModules(self): self.eI = EngineInterface(objectMode=False) self.sE = ScriptExecuter() self.detectors = [] self.sE.addContext("Entity", self) self.sE.addContext("Detector", Detector) def installCustomCode(self): if self.scriptName: self.sE.execute(self.scriptName) def reconstructObject(self, objData): self.initVolatileModules() path = LOCATIONS["Entity"] cR = ContentReader(path+objData["name"]) objectType = cR.get("type") sourcename = cR.get("name") objname = sourcename resource = cR.get("resourcePath") scriptName = cR.get("scriptPath") flags = cR.get("flags") props = cR.get("properties") if objectType == "Object": self.eI.loadLibrary(path+resource, False) extra = {} #elif objectType == "Light": # extra = cR.get("lightSettings") # if extra["type"] == "SUN": # objname = "SunBase" # elif extra["type"] == "SPOT": # objname = "SpotBase" # elif extra["type"] == "NORMAL": # objname = "LightBase" #elif objectType == "Camera": # objname = "CameraBase" # extra = cR.get("cameraSettings") self.createObject(objname, sourcename, self.GUID, objData["pos"], objData["rot"], objData["sca"], props, extra) #Install custom code self.installCustomCode() def removeCustomCode(self): for i in dir(self): if "function" in type(getattr(self, i)): setattr(self, i, None) def createObject(self, objname, sourcename, GUID, pos, rot, sca, props, extra): self.gameObject = self.eI.createObject(objname, GUID, pos, rot, sca) if self.gameObject: self.GUID = self.gameObject["GUID"] self.oP("Added entity %s." % sourcename) else: self.oP("Failed to add entity %s." % sourcename) if self.gameObject: self.processProperties(props) # if objname == "CameraBase": # self.configureCamera(extra) # elif objname in ["LightBase", "SpotBase", "SunBase"]: # self.configureLight(extra) def __str__(self): return self.name + " - " + self.GUID def __repr__(self): return self.name + " - " + self.GUID def addDetector(self, detector): self.detectors.append(detector) def kill(self, side): if hasattr(self, "destruct"): self.destruct(side) self.eI.removeObject(self.GUID) def processFlags(self, flags): for flag in flags: if hasattr(self, flag): setattr(self, flag, flags[flag]) def processProperties(self, props): for prop in props.keys(): self.gameObject[prop] = props[prop] def load(self, location, name): path = LOCATIONS[location] cR = ContentReader(path+name) return cR def playAction(self, name, onEnd=None): action = self.getAction(name) if not action: cR = self.load("Animation", name) name = cR.get("name") mode = cR.get("mode") skeleton = cR.get("skeleton") times = [cR.get("start"), cR.get("end")] layer = cR.get("layer") targetChild = cR.get("targetChild") action = Action(self, name, [mode, skeleton], times, layer, targetChild) action.onEnd = onEnd action.play() self.actions.append(action) def stopAction(self, name): for action in self.actions: if action.action == name: action.stop() self.actions.remove(action) return def getAction(self, name): for action in self.actions: if action.action == name: return action def playFrameAction(self, name, frame): action = self.getAction(name) if not action: cR = self.load("Animation", name) name = cR.get("name") mode = cR.get("mode") skeleton = cR.get("skeleton") times = [frame, frame+1] layer = cR.get("layer") targetChild = cR.get("targetChild") action = Action(self, name, [mode, skeleton], times, layer, targetChild) action.play() self.actions.append(action) else: action.start = frame action.end = frame+1 action.play() def clearStances(self): for action in self.actions: if action.action[:len(action.action)-7] == "_stance": self.stopAction(action.action) def checkPhysics(self): for detector in self.detectors: result = detector.triggered() if result and hasattr(detector, "returnFunction"): detector.returnFunction(result) def checkAnimation(self): for action in self.actions: isOver = action.obj.getActionFrame(action.layer) == action.end isPlay = action.mode == 0 isStance = "_stance" == action.action[:len(action.action)-7] if isOver and isPlay and not isStance: self.stopAction(action.action) if action.onEnd: action.onEnd() #def configureCamera(self, extra): # self.gameObject.fov = extra["fov"] # self.gameObject.near = extra["near"] # self.gameObject.far = extra["far"] #def configureLight(self, extra): # self.gameObject.color = (extra["r"], extra["g"], extra["b"]) # self.gameObject.type = getattr(self.gameObject, extra["type"]) # self.gameObject.energy = float(extra["energy"]) # self.gameObject.spotsize = float(extra["spotsize"]) def trackTo(self, obj): #vector = self.gameObject.getVectTo(obj)[1] # #self.gameObject.alignAxisToVect(vector, 1) #ori = self.gameObject.worldOrientation.to_euler() x = self.gameObject.worldPosition[0] - obj.worldPosition[0] y = self.gameObject.worldPosition[1] - obj.worldPosition[1] if self.gameObject.worldPosition[0] > obj.worldPosition[0]: adjustment = 90 else: adjustment = 270 try: self.gameObject.worldOrientation = (0, 0, d2r(r2d(atan(y/x))+adjustment)) except: if y > 0: self.gameObject.worldOrientation = (0, 0, d2r(180)) else: self.gameObject.worldOrientation = (0, 0, d2r(0))
import bge from engineinterface import EngineInterface from paths import LOCATIONS cont = bge.logic.getCurrentController() own = cont.owner if own["queue"] == "": own["queue"] = [] own["eI"] = EngineInterface() def addToWaypoints(item, item1, item2): own["queue"].append([item, item1, item2]) bge.logic.globalDict["addToWaypoints"] = addToWaypoints #Create waypoints for item in own["queue"]: own["eI"].loadLibrary(LOCATIONS["UI"] + item[0]) waypoint = own["eI"].createWaypoint(item[1]) waypoint["targetGUID"] = item[2] own["queue"] = [] #Update cam mirrorCam = own["eI"].getWaypointsScene().objects["MirrorCam"] referenceCam = own["eI"].getMainScene().active_camera mirrorCam.worldPosition = referenceCam.worldPosition mirrorCam.worldOrientation = referenceCam.worldOrientation mirrorCam.fov = referenceCam.fov
from engineinterface import EngineInterface eI = EngineInterface() client = eI.getGlobal("client") client.configure("cl_showmouse", 1) client.playVideo("intro") client.addInterface("TitleScreen")
class InputReceiver(): def __init__(self): self.oP = OutPipe("InputReceiver", 0) self.cR = ConfigReader(GAME_PATH + "controls") self.sE = ScriptExecuter() self.eI = EngineInterface(objectMode=False) self.keyboard = self.eI.getKeyboard() self.mouse = self.eI.getMouse() self.tH = TypingHandler(self.keyboard) self.pairs = {} self.responses = {} self.oldKeyboard = self.keyboard.events self.oldMouse = self.mouse.events self.sE.addContext("Input", self) self.sE.execute(INPUT_PATH + "csp") self.sE.execute(INPUT_PATH + "input") self.keyEvents = [] self.readControls() self.locked = False self.xsens = 50 self.ysens = 50 self.inverted = 0 self.predict = False self.recent = {} self.oP("Initialized.") def addEvent(self, event): if not event in self.recent.keys(): self.keyEvents.append(["INPUT", "COMMAND", event]) if not type(event) == type(tuple()): self.recent[event] = time.time() if self.predict: self.callClientSidePrediction(event) def callClientSidePrediction(self, event): if not type(event) == type(tuple()): if hasattr(self, "csp_" + event): getattr(self, "csp_" + event)() else: if hasattr(self, "csp_look"): getattr(self, "csp_look")(event) def readControls(self): keys = self.cR.getAllOptions("CONTROLS") for key in keys: keyString = self.cR.get("CONTROLS", key) keyCode = self.eI.getKeyCode(keyString) try: self.pairs[keyCode] = getattr(self, key) self.oP("Read in key response %s successfully." % key) except: self.oP("Failed to read in key response %s successfully." % key) def checkControls(self): for keyCode in self.pairs.keys(): if keyCode in self.keyboard.events and not self.locked: if self.keyboard.events[keyCode] == self.eI.l.KX_INPUT_ACTIVE: self.callCommand("KEYBOARD", keyCode) elif self.keyboard.events[ keyCode] == self.eI.l.KX_INPUT_JUST_ACTIVATED: self.callCommand("KEYBOARD", keyCode) elif self.keyboard.events[ keyCode] == self.eI.l.KX_INPUT_JUST_RELEASED: self.callCommand("KEYBOARD", keyCode) elif keyCode in self.mouse.events: if self.mouse.events[keyCode] == self.eI.l.KX_INPUT_ACTIVE: self.callCommand("MOUSE", keyCode) elif self.mouse.events[ keyCode] == self.eI.l.KX_INPUT_JUST_ACTIVATED: self.callCommand("MOUSE", keyCode) elif self.mouse.events[ keyCode] == self.eI.l.KX_INPUT_JUST_RELEASED: self.callCommand("MOUSE", keyCode) self.oldKeyboard = self.keyboard.events self.oldMouse = self.mouse.events #Handle the "recent" spam blocker keys = self.recent.keys() for key in keys: if abs(self.recent[key] - time.time()) > 0.1: del self.recent[key] break if self.locked: self.tH.process() def callCommand(self, mode, keyCode): if mode == "KEYBOARD": state = self.getState(self.keyboard.events[keyCode], self.oldKeyboard[keyCode]) elif mode == "MOUSE": state = self.getState(self.mouse.events[keyCode], self.oldMouse[keyCode]) consumed = False if state == "DEACTIVATE" and keyCode in [ self.eI.e.LEFTMOUSE, self.eI.e.RIGHTMOUSE ]: consumed = self.checkInterfaceClick(keyCode, self.mouse.position) if not consumed and not keyCode in [ self.eI.e.MOUSEX, self.eI.e.MOUSEY ]: self.pairs[keyCode](state) elif keyCode in [self.eI.e.MOUSEX, self.eI.e.MOUSEY]: pos = self.mouse.position self.pairs[keyCode](pos) def checkInterfaceClick(self, keyCode, pos): return self.eI.getGlobal("client").inputClick(keyCode, pos) def getState(self, newstate, oldstate): if newstate == self.eI.l.KX_INPUT_ACTIVE: if oldstate == self.eI.l.KX_INPUT_ACTIVE: return "ACTIVE" elif oldstate == self.eI.l.KX_INPUT_NONE: return "ACTIVATE" elif oldstate == self.eI.l.KX_INPUT_JUST_ACTIVATED: return "ACTIVATE" elif oldstate == self.eI.l.KX_INPUT_JUST_RELEASED: return "ACTIVATE" if newstate == self.eI.l.KX_INPUT_NONE: if oldstate == self.eI.l.KX_INPUT_ACTIVE: return "DEACTIVATE" elif oldstate == self.eI.l.KX_INPUT_NONE: return "INACTIVE" elif oldstate == self.eI.l.KX_INPUT_JUST_ACTIVATED: return "DEACTIVATE" elif oldstate == self.eI.l.KX_INPUT_JUST_RELEASED: return "DEACTIVATE" if newstate == self.eI.l.KX_INPUT_JUST_ACTIVATED: if oldstate == self.eI.l.KX_INPUT_ACTIVE: return "ACTIVATE" elif oldstate == self.eI.l.KX_INPUT_NONE: return "ACTIVATE" elif oldstate == self.eI.l.KX_INPUT_JUST_ACTIVATED: return "ACTIVATE" elif oldstate == self.eI.l.KX_INPUT_JUST_RELEASED: return "ACTIVATE" if newstate == self.eI.l.KX_INPUT_JUST_RELEASED: if oldstate == self.eI.l.KX_INPUT_ACTIVE: return "DEACTIVATE" elif oldstate == self.eI.l.KX_INPUT_NONE: return "DEACTIVATE" elif oldstate == self.eI.l.KX_INPUT_JUST_ACTIVATED: return "DEACTIVATE" elif oldstate == self.eI.l.KX_INPUT_JUST_RELEASED: return "DEACTIVATE"
class Client(GameSide): def __init__(self): '''Initializes the client.''' self.mode = "client" self.oP = OutPipe("Client", 0) self.eI = EngineInterface(objectMode=True) self.vP = VideoPlayer() self.sE = ScriptExecuter() self.iR = InputReceiver() self.l = Localizer(self) self.pA = PhysicsApplicator(self) self.sH = ShaderHandler() self.nC = None self.sE.addContext("Client", self) self.cvars = { #Low level settings "cl_update": 1, "cl_synced": 0, "cl_addr": "0.0.0.0", "cl_oport": 7777, "cl_iport": 7778, "cl_netlog": 0, "cl_game": 0, "cl_startscript": "", "cl_master": 0, "cl_predict": 1, "cl_smooth": 0, "cl_name": "Player", "cl_password": "", "cl_camera": "", "cl_lockcontrols": 1, "cl_showmouse": 1, "cl_xsens": 50, "cl_ysens": 50, "cl_inverted": 0, "cl_netping": 0, #High level settings "cl_language": "en", "cl_subtitles": 1, "cl_width": 1280, "cl_height": 720, "cl_fullscreen": 0, "cl_motionblur": 0, "cl_motionblur_amount": 0, "cl_anisotropic": 1, "cl_mipmap": "none", "cl_vsync": "off", "cl_musicvolume": 10, "cl_dialogvolume": 10, "cl_soundvolume": 10, "cl_mastervolume": 10, #Server shared settings "sv_level": "", "sv_gamemode": "", "sv_game": 0, "sv_background_red": 0, "sv_background_green": 0, "sv_background_blue": 0, "sv_background_alpha": 0, } self.netVars = {} self.chatMessages = [] self.interfaces = [] self.entities = [] self.level = None self.gameEvents = [] self.updateNetwork() #self.startLoop() self.forceUpdateCVars() self.keepAliveTicker = 0 self.trackedProperties = [] loadClient(self) self.oP("Initialized.") def forceUpdateCVars(self): '''Forces all the cVars to run their updaters as though they had just been set.''' for key in self.cvars.keys(): if not "sv_" == key[:3]: self.configure(key, self.get(key), override=True) self.oP("Force updated cVars.") def configure(self, key, val, fromServer=False, override=False): '''Configure a cVar.''' changed = False if key in self.cvars.keys() and (not "sv_" == key[:3] or fromServer): #Switch for int if type(self.cvars[key]) == type(0): val = int(val) #Used for functions if type(self.cvars[key]) == type(self.configure): self.cvars[key](val) self.oP("CVar %s executed." % key) else: if val != self.cvars[key] or override: changed = True self.cvars[key] = val self.oP("CVar %s configured to %s (%s)." % (key, val, str(type(val)).replace( "<class '", "").replace("'>", ""))) elif "sv_" == key[:3] and not fromServer and key in self.cvars.keys( ) and self.cvars[key] != val: self.sendEvent(["SYSTEM", "CVARS", [key, val]]) self.oP("Asking server to change CVar %s." % key) else: self.oP("CVar %s not present." % key) if changed: self.updateGame(key) def connectGame(self): '''Connects to a game.''' self.oP("Connecting to game.") self.nC.connect((self.get("cl_addr"), self.get("cl_oport"))) self.configure("cl_game", 1) self.configure("cl_synced", 0) def disconnectGame(self): '''Disconnects from a game.''' self.oP("Disconnecting from a game.") self.updateNetwork() self.configure("cl_game", 0) self.configure("cl_synced", 0) self.configure("cl_update", 1) self.oP("Disconnected from game.") def updateGame(self, key): '''Reacts to changes to the cVars.''' if key == "cl_startscript": self.sE.addContext("Client", self) self.sE.execute(self.get("cl_startscript")) elif key in ["cl_iport"]: self.updateNetwork() elif key == "cl_addr": if self.get("cl_addr") == "0.0.0.0": self.configure("cl_addr", "127.0.0.1") elif key == "cl_name": self.sendEvent(["SYSTEM", "NAME", self.get("cl_name")]) elif key == "sv_level" and not self.get("cl_master"): if self.get("sv_game"): self.setLevel(self.get("sv_level")) elif key == "sv_game" and not self.get("cl_master"): if self.get("sv_game"): self.setLevel(self.get("sv_level")) else: self.endLevel() elif key in [ "sv_background_red", "sv_background_green", "sv_background_blue", "sv_background_alpha" ] and not self.get("cl_master"): self.eI.setBackgroundColor((self.getBackgroundColor())) elif key == "cl_width" or key == "cl_height": self.eI.setResolution(self.get("cl_width"), self.get("cl_height")) elif key == "cl_fullscreen": self.eI.setFullscreen(self.get("cl_fullscreen")) elif key == "cl_motionblur" or key == "cl_motionblur_amount": self.eI.setMotionBlur(self.get("cl_motionblur"), self.get("cl_motionblur_amount")) elif key == "cl_anisotropic": self.eI.setAnisotropic(self.get("cl_anisotropic")) elif key == "cl_mipmap": self.eI.setMipmapping(self.get("cl_mipmap")) elif key == "cl_vsync": self.eI.setVSync(self.get("cl_vsync")) elif key == "cl_camera" and self.get("cl_camera") != "": self.eI.setCamera(self.get("cl_camera")) elif key == "cl_mastervolume": launcher = self.eI.getGlobal("launcher") if launcher: launcher.sound.setMasterVolume(self.get("cl_mastervolume")) elif key == "cl_musicvolume": launcher = self.eI.getGlobal("launcher") if launcher: launcher.sound.setMusicVolume(self.get("cl_musicvolume")) elif key == "cl_dialogvolume": launcher = self.eI.getGlobal("launcher") if launcher: launcher.sound.setDialogVolume(self.get("cl_dialogvolume")) elif key == "cl_soundvolume": launcher = self.eI.getGlobal("launcher") if launcher: launcher.sound.setSoundVolume(self.get("cl_soundvolume")) elif key == "cl_subtitles": launcher = self.eI.getGlobal("launcher") if launcher: launcher.sound.subtitles = self.get("cl_subtitles") elif key == "cl_language": launcher = self.eI.getGlobal("launcher") if launcher: launcher.sound.language = self.get("cl_language") elif key == "cl_lockcontrols": self.iR.locked = self.get("cl_lockcontrols") elif key == "cl_showmouse": self.eI.setMouseState(self.get("cl_showmouse")) elif key == "cl_xsens": self.iR.xsens = self.get("cl_xsens") elif key == "cl_ysens": self.iR.ysens = self.get("cl_ysens") elif key == "cl_inverted": self.iR.inverted = self.get("cl_inverted") elif key == "cl_predict": self.iR.predict = self.get("cl_predict") if not self.get("cl_predict"): for GUID in self.pA.blacklistedGUIDs: self.removeFromRotationBlacklist(GUID) elif key == "cl_smooth": self.pA.smooth = self.get("cl_smooth") elif key == "cl_netlog": if self.get("cl_netlog"): self.nC.configure("DEBUG", True) self.nC.configure("VERBOSE", True) else: self.nC.configure("DEBUG", False) self.nC.configure("VERBOSE", False) elif key == "cl_netping": self.nC.pingcount = self.get("cl_netping") def updateNetwork(self): '''Update the network module for changes to port or addr''' self.purgeNetwork() self.nC = NetCore() if self.get("cl_netlog"): self.nC.configure("DEBUG", True) self.nC.configure("VERBOSE", True) else: self.nC.configure("DEBUG", False) self.nC.configure("VERBOSE", False) self.nC.pingcount = self.get("cl_netping") self.nC.configure("NAME", "Client") self.nC.setProtocol("UDP") self.nC.configure("PORT", self.get("cl_iport")) self.nC.initialize() def purgeNetwork(self): '''Destroys the NetCore once and for all.''' if self.nC: self.nC.clear() self.nC.destroy() self.nC = None def startGameRemote(self): '''Used to connect to another person's game.''' self.oP("Starting game (remote)...") self.configure("cl_master", 0) self.configure("cl_update", 1) self.configure("cl_predict", 1) self.connectGame() def startGameFull(self): '''Used if you want the lobby when you start up a game.''' self.oP("Starting game (full)...") self.configure("cl_master", 1) self.configure("cl_update", 0) self.configure("cl_predict", 0) launcher = self.eI.getGlobal("launcher") if launcher: launcher.bootServer() self.oP("Booted server from client (Full).") self.configure("cl_addr", launcher.s.get("sv_addr")) self.connectGame() def startGameFast(self, level, gamemode, singleplayer=True): '''Used if you want to go straight to the game, usually used for singleplayer.''' self.oP("Starting game (fast)...") self.configure("cl_master", 1) self.configure("cl_update", 0) self.configure("cl_predict", 0) self.configure("cl_game", 1) self.updateNetwork() launcher = self.eI.getGlobal("launcher") if launcher: launcher.bootServer() self.oP("Booted server from client (Fast).") launcher.s.configure("sv_level", level) launcher.s.configure("sv_gamemode", gamemode) launcher.s.configure("sv_game", 1) if singleplayer: launcher.s.configure("sv_singleplayer", 1) else: launcher.s.configure("sv_singleplayer", 0) self.configure("cl_addr", launcher.s.get("sv_addr")) self.connectGame() def endGame(self): '''Ends the game instance and disconnects.''' self.oP("Ending game session...") self.disconnectGame() self.endLevel() launcher = self.eI.getGlobal("launcher") if launcher and self.get("cl_master") and launcher.s: launcher.s.quitGame() launcher.s = None def quitGame(self): '''Quits the game completely.''' self.oP("Shutting down...") self.endGame() self.purgeNetwork() self.eI.quitGame() def setMusic(self, music): '''Sets the music track.''' launcher = self.eI.getGlobal("launcher") launcher.sound.playMusic(music) self.oP("Set music to %s." % music) def stopMusic(self): '''Stops the music track.''' launcher = self.eI.getGlobal("launcher") launcher.sound.stopMusic() self.oP("Stopped music.") def playSound(self, sound, emitter=None): '''Plays the sound.''' launcher = self.eI.getGlobal("launcher") if emitter: launcher.sound.playSound(sound, emitter.gameObject) else: launcher.sound.playSound(sound) self.oP("Started playing sound %s." % sound) def stopSound(self, handle): '''Stops a sound.''' launcher = self.eI.getGlobal("launcher") GUID, name = launcher.sound.stopSound(handle) self.oP("Stopped sound %s." % name) def stopSoundByGUID(self, GUID, name): '''Stops a sound.''' launcher = self.eI.getGlobal("launcher") launcher.sound.stopSoundByGUID(GUID, name) self.oP("Stopped sound %s." % name) def playDialog(self, sound, emitter): '''Plays a dialog line.''' launcher = self.eI.getGlobal("launcher") if emitter: launcher.sound.playDialog(sound, emitter.gameObject) else: launcher.sound.playDialog(sound) self.oP("Playing dialog %s." % sound) def stopDialog(self, handle): '''Stops a dialog line.''' launcher = self.eI.getGlobal("launcher") GUID, name = launcher.sound.stopDialog(handle) self.oP("Stopped dialog %s." % name) def stopDialogByGUID(self, GUID, name): '''Stops a dialog line.''' launcher = self.eI.getGlobal("launcher") launcher.sound.stopDialogByGUID(GUID, name) self.oP("Stopped dialog %s." % name) def enableShader(self, index, name, mode): '''Enables a shader as a filter for the entire screen.''' self.sH.enableShader(index, name, mode) def disableShader(self, index): '''Disables a shader that was filtering the entire screen.''' self.sH.disableShader(index) def playVideo(self, video): '''Plays a video.''' self.vP.playVideo(video) self.oP("Started video %s." % video) def stopVideo(self): '''Stops a video.''' self.vP.stopVideo() self.oP("Stopped video.") def replaceMesh(self, ent, meshName): '''Replaces the mesh of an Entity.''' cR = self.load("Mesh", meshName) name = cR.get("name") resourcePath = cR.get("resourcePath") self.loadLibrary("Mesh", resourcePath, mesh=True) ent.gameObject.replaceMesh(meshName, True, True) self.oP("Replaced mesh of %s with %s." % (ent.GUID, meshName)) def addInterface(self, name): '''Adds an interface.''' if not self.getInterfaceByName(name): cR = self.load("UI", name) name = cR.get("name") resource = cR.get("resourcePath") scriptName = cR.get("scriptPath") #self.loadLibrary("UI", resource) self.oP("Creating interface %s." % name) self.interfaces.append(Interface(name, resource, scriptName)) else: self.oP("Interface %s already exists, not created." % name) def removeInterface(self, name): '''Removes an interface.''' interface = self.getInterfaceByName(name) if interface: self.oP("Removing interface %s." % name) self.interfaces.remove(interface) interface.kill() def removeAllInterfaces(self): '''Removes all interfaces.''' self.oP("Removing all interfaces.") names = [] for interface in self.interfaces: names.append(interface.name) for name in names: self.removeInterface(name) def getInterfaceByName(self, name): '''Gets an interface by name.''' for interface in self.interfaces: if interface.name == name: return interface def addMarker(self, name, GUID): '''Adds a marker tracking the specified Entity.''' cR = self.load("UI", name) name = cR.get("name") resource = cR.get("resourcePath") self.eI.getGlobal("addToWaypoints")(resource, name, GUID) self.oP("Added waypoint %s tracking %s." % (name, GUID)) def removeMarker(self, GUID): '''Removes all markers tracking an Entity.''' for obj in self.eI.getWaypointsScene().objects: if "targetGUID" in obj and obj["targetGUID"] == GUID: obj.endObject() self.oP("Removed waypoints tracking %s." % GUID) def inputClick(self, keyCode, pos): '''Checks for the interface clicks.''' obj, scene = self.eI.getMouseOverObjectScene(pos) if obj and scene: for interface in self.interfaces: if interface.name == self.eI.getTerminalParent(obj).name: interface.onClick(obj.name) return True for i in self.entities: if obj == i.gameObject or obj in i.gameObject.childrenRecursive: i.onClick(obj.name) return True return False def getDisconnectReaction(self): '''Gets the reaction function for disconnecting from the server.''' self.sE.execute(NETSCRIPT_PATH + "disconnect") return self.disconnectReaction def addToRotationBlacklist(self, GUID): '''Adds a GUID to the rotation blacklist.''' if not GUID in self.pA.blacklistedGUIDs: self.pA.blacklistedGUIDs.append(GUID) def removeFromRotationBlacklist(self, GUID): '''Removes a GUID from the rotation blacklist.''' if GUID in self.pA.blacklistedGUIDs: self.pA.blacklistedGUIDs.remove(GUID) def sendInterfaceEvent(self, event, aux=None): '''Sends an interface event.''' self.sendEvent(["INPUT", "INTERFACE", [event, aux]]) def sendChatMessage(self, msg): '''Sends a chat message.''' self.sendEvent(["SYSTEM", "CHAT", msg]) def sendGameEvent(self, mode, data): '''Sends a game event.''' self.sendEvent(["GAME", mode, data]) def sendEvent(self, event): '''Sends an event to the server.''' if event[0] == "INPUT" or event == "KEEPALIVE": mode = "FAF" elif event[0] in ["SYSTEM", "GAME", "NETWORK"]: mode = "RT" if self.nC.clients: server = self.nC.clients[0] server.send(event, mode) def recvEvent(self, event): '''Handles an event from the server.''' if event[0] == "PHYSICS" and self.get("cl_update"): self.pA.update(event) if event[0] == "SYSTEM": if event[1] == "CVARS": self.configure(event[2][0], event[2][1], fromServer=True) elif event[1] == "NETVARS": self.netVars[event[2][0]] = event[2][1] elif event[1] == "SOUND_PLAY" and self.get("cl_update"): entity = self.getEntityByGUID(event[2][0]) self.playSound(event[2][1], entity) elif event[1] == "SOUND_STOP" and self.get("cl_update"): self.stopSoundByGUID(event[2][0], event[2][1]) elif event[1] == "DIALOG_PLAY" and self.get("cl_update"): entity = self.getEntityByGUID(event[2][0]) self.playDialog(event[2][1], entity) elif event[1] == "DIALOG_STOP" and self.get("cl_update"): self.stopDialogByGUID(event[2][0], event[2][1]) elif event[1] == "MUSIC_PLAY" and self.get("cl_update"): self.setMusic(event[2][0]) elif event[1] == "MUSIC_STOP" and self.get("cl_update"): self.stopMusic() elif event[1] == "SET_CAMERA": self.configure("cl_camera", event[2]) elif event[1] == "INTERFACE_CREATE": self.addInterface(event[2]) elif event[1] == "INTERFACE_REMOVE": self.removeInterface(event[2]) elif event[1] == "CHAT": self.chatMessages.append(event[2]) def loop(self): '''Does everything basically.''' #cl = OptiClock() #Detector Index if not self.get("cl_master"): self.updateDetectorIndex() #cl.clockIn("DetectorIndex") #KEEP ALIVE self.keepAliveTicker += 1 if self.keepAliveTicker % 600 == 0: self.sendEvent("KEEPALIVE") #cl.clockIn("KeepAlive") #Do Things####################### #Read in controls self.iR.checkControls() #cl.clockIn("Input") #Update Video Player self.vP.loop() #cl.clockIn("VideoPlayer") if self.get("cl_update"): #Update localization self.l.loop() #cl.clockIn("Localization") #Apply shaders self.sH.loop() #cl.clockIn("Shaders") #Run object code for ent in self.entities: if hasattr(ent, "loop"): ent.checkAnimation() ent.loop(self, "client") #Run interface code #cl.clockIn("Entities") if self.level: if hasattr(self.level, "loop"): self.level.loop(self, "client") #cl.clockIn("Level") for interface in self.interfaces: if hasattr(interface, "loop"): try: interface.loop() except: pass #cl.clockIn("Interface") if self.nC: #Send Things##################### for key in self.iR.keyEvents: self.sendEvent(key) for event in self.gameEvents: self.sendEvent(event) self.gameEvents = [] self.iR.keyEvents = [] #cl.clockIn("SendLoop") #Recv Things##################### if self.nC.clients: server = self.nC.clients[0] packet = server.recv() if packet: payload = packet.getPayload() try: data = eval(payload) except: data = None if data: self.recvEvent(data) #cl.clockIn("RecvLoop") #Initial sync if self.nC.clients: server = self.nC.clients[0] if not self.get("cl_synced"): server.disconnectFunc = self.getDisconnectReaction() self.sendEvent(["SYSTEM", "NAME", self.get("cl_name")]) self.sendEvent( ["SYSTEM", "PASSWORD", self.get("cl_password")]) self.sendEvent(["SYSTEM", "PHYSICS", "FORCEUPDATE"]) self.configure("cl_synced", 1) #cl.clockIn("Sync") #KILL THINGS################################################### kill = self.nC.pullKillQueue() if kill: kill() #cl.clockIn("Kill") self.nC.loop()