//this function is responsible for looping through all the keys and giving out the NEW player number //remember this instance has not been added yet public static int getNewPlayerNumber(string controlName) { int player = EasyWiFiUtilities.getHighestPlayerNumber() + 1; int returnIndex = 0; bool foundControl = false; for (int i = 0; i <= player; i++) { foundControl = EasyWiFiUtilities.isPlayerNumberOccupied(i, controlName); if (foundControl == false) { //we found no control with this player number (lowest yet so return it) returnIndex = i; break; } } return(returnIndex); }
//for our network traffic on both ends we are essentially having strings (converted in/out for byte[] on the send/recieve //these methods essentially will be one line in the string (remember a client will have more than one controller type) //this method is called when a packet is received on a connection that is marked as disconnected due to a timeout //this can occur in game usecases when the player suspends the app and restarts and expects the controller to still work //because the app wasn't executing having the server sending a message stating hey you timed out is useless //instead because our design is player based simply check to see if another controller has been assigned this player number //if not then just change the player number back and proceed as normal //if another controller has then get the next available player number and then notify the callback of a changed connection public void reuseOrGetAnotherConnection(int previousPlayerNumber) { if (EasyWiFiUtilities.isPlayerNumberOccupied(previousPlayerNumber, clientKey)) { logicalPlayerNumber = EasyWiFiController.getNewPlayerNumber(clientKey); } else { logicalPlayerNumber = previousConnectionPlayerNumber; } lastReceivedPacketTime = DateTime.UtcNow; justReconnected = true; //take this time to reactivate all of the controls from this IP address so callback only get fired once BaseControllerType temp; string[] splitter = { clientKey }; String[] clientIP = serverKey.Split(splitter, StringSplitOptions.RemoveEmptyEntries); if (EasyWiFiController.controllerDataDictionary != null) { foreach (string key in EasyWiFiController.controllerDataDictionary.Keys) { temp = EasyWiFiController.controllerDataDictionary[key]; if (temp.serverKey.Contains(clientIP[0])) { temp.justReconnected = true; temp.lastReceivedPacketTime = DateTime.UtcNow; temp.logicalPlayerNumber = logicalPlayerNumber; } } } //send the callback for a connection EasyWiFiController.isConnect = true; EasyWiFiController.lastConnectedPlayerNumber = logicalPlayerNumber; EasyWiFiController.forceConnectionRefresh(); }
//this method is responsible for registering a control which will instance a specific controller type //add it to the data structure and set its key and return it //There are two ways this method is called, one on the client the UI script in its startup registers it client side //The second way is the server when a client sends over its inventory public static string registerControl(string type, string name, string IP = "0") { BaseControllerType controller; string key = ""; switch (type) { case EasyWiFiConstants.CONTROLLERTYPE_DPAD: controller = new DpadControllerType(); controller.controllerType = EasyWiFiConstants.CONTROLLERTYPE_DPAD; break; case EasyWiFiConstants.CONTROLLERTYPE_JOYSTICK: controller = new JoystickControllerType(); controller.controllerType = EasyWiFiConstants.CONTROLLERTYPE_JOYSTICK; break; case EasyWiFiConstants.CONTROLLERTYPE_BUTTON: controller = new ButtonControllerType(); controller.controllerType = EasyWiFiConstants.CONTROLLERTYPE_BUTTON; break; case EasyWiFiConstants.CONTROLLERTYPE_TOUCHPAD: controller = new TouchpadControllerType(); controller.controllerType = EasyWiFiConstants.CONTROLLERTYPE_TOUCHPAD; break; case EasyWiFiConstants.CONTROLLERTYPE_SLIDER: controller = new SliderControllerType(); controller.controllerType = EasyWiFiConstants.CONTROLLERTYPE_SLIDER; break; case EasyWiFiConstants.CONTROLLERTYPE_PINCHZOOMTOUCHPAD: controller = new PinchZoomTouchpadControllerType(); controller.controllerType = EasyWiFiConstants.CONTROLLERTYPE_PINCHZOOMTOUCHPAD; break; case EasyWiFiConstants.CONTROLLERTYPE_ACCELEROMETER: controller = new AccelerometerControllerType(); controller.controllerType = EasyWiFiConstants.CONTROLLERTYPE_ACCELEROMETER; break; case EasyWiFiConstants.CONTROLLERTYPE_FLOAT: controller = new FloatBackchannelType(); controller.controllerType = EasyWiFiConstants.CONTROLLERTYPE_FLOAT; break; case EasyWiFiConstants.CONTROLLERTYPE_INT: controller = new IntBackchannelType(); controller.controllerType = EasyWiFiConstants.CONTROLLERTYPE_INT; break; case EasyWiFiConstants.CONTROLLERTYPE_DOUBLE: controller = new DoubleBackchannelType(); controller.controllerType = EasyWiFiConstants.CONTROLLERTYPE_DOUBLE; break; case EasyWiFiConstants.CONTROLLERTYPE_BOOL: controller = new BoolBackchannelType(); controller.controllerType = EasyWiFiConstants.CONTROLLERTYPE_BOOL; break; case EasyWiFiConstants.CONTROLLERTYPE_DECIMAL: controller = new DecimalBackchannelType(); controller.controllerType = EasyWiFiConstants.CONTROLLERTYPE_DECIMAL; break; case EasyWiFiConstants.CONTROLLERTYPE_STRING: controller = new StringBackchannelType(); controller.controllerType = EasyWiFiConstants.CONTROLLERTYPE_STRING; break; case EasyWiFiConstants.CONTROLLERTYPE_GYRO: controller = new GyroControllerType(); controller.controllerType = EasyWiFiConstants.CONTROLLERTYPE_GYRO; break; case EasyWiFiConstants.BACKCHANNELTYPE_FLOAT: controller = new FloatBackchannelType(); controller.controllerType = EasyWiFiConstants.BACKCHANNELTYPE_FLOAT; break; case EasyWiFiConstants.BACKCHANNELTYPE_INT: controller = new IntBackchannelType(); controller.controllerType = EasyWiFiConstants.BACKCHANNELTYPE_INT; break; case EasyWiFiConstants.BACKCHANNELTYPE_DOUBLE: controller = new DoubleBackchannelType(); controller.controllerType = EasyWiFiConstants.BACKCHANNELTYPE_DOUBLE; break; case EasyWiFiConstants.BACKCHANNELTYPE_BOOL: controller = new BoolBackchannelType(); controller.controllerType = EasyWiFiConstants.BACKCHANNELTYPE_BOOL; break; case EasyWiFiConstants.BACKCHANNELTYPE_DECIMAL: controller = new DecimalBackchannelType(); controller.controllerType = EasyWiFiConstants.BACKCHANNELTYPE_DECIMAL; break; case EasyWiFiConstants.BACKCHANNELTYPE_STRING: controller = new StringBackchannelType(); controller.controllerType = EasyWiFiConstants.BACKCHANNELTYPE_STRING; break; default: //should not occur Debug.Log("Error: a controller type that isn't defined was registered"); controller = new DpadControllerType(); controller.controllerType = EasyWiFiConstants.CONTROLLERTYPE_DPAD; break; } if (peerType.Equals(EasyWiFiConstants.PEERTYPE_CLIENT)) { //on the client we care what both the client and server key is but only client is known at registration time //the server key is discovered when the server responds to the inventory and will be populated then controller.clientKey = name; key = controller.clientKey; } if (peerType.Equals(EasyWiFiConstants.PEERTYPE_SERVER)) { controller.serverKey = IP + name; controller.clientKey = name; controller.clientIP = IP; controller.logicalPlayerNumber = getNewPlayerNumber(name); controller.lastReceivedPacketTime = DateTime.UtcNow; lastConnectedPlayerNumber = controller.logicalPlayerNumber; isConnect = true; key = controller.serverKey; } if (!controllerDataDictionary.ContainsKey(key)) { //brand new first time here controllerDataDictionary.Add(key, controller); isNew = true; } else if (controllerDataDictionary[key].logicalPlayerNumber == EasyWiFiConstants.PLAYERNUMBER_DISCONNECTED) { //already here just reassign (original disconnected and new one is here) //we will only change the player number if it's been occupied in between controllerDataDictionary[key].lastReceivedPacketTime = DateTime.UtcNow; controllerDataDictionary[key].justReconnected = true; if (!EasyWiFiUtilities.isPlayerNumberOccupied(controllerDataDictionary[key].previousConnectionPlayerNumber, controllerDataDictionary[key].clientKey)) { //not occupied assign it's previous number controllerDataDictionary[key].logicalPlayerNumber = controllerDataDictionary[key].previousConnectionPlayerNumber; } else { //occupied give it the lowest available number controllerDataDictionary[key].logicalPlayerNumber = controller.logicalPlayerNumber; } isNew = true; } else { //was already here and isn't currently marked as disconnected (most likely a delayed packet) isNew = false; } return(key); }