private void delayedLiveBalance(DateTime now, bool force) { /* save the original team and squad for each player */ List<PlayerProfile> players = getPlayersProfile(""); players.ForEach(delegate(PlayerProfile pp) { if (pp.getDelayedTeamId() > 0) DebugWrite("Un-flagging ^b" + pp + "^n for delayed move", 3); pp.resetDelayedTeamSquad(); pp.saveTeamSquad(); }); live_balancer = true; /* for delayed live balance we want to do it all virtually, and only move players after they respawn */ bool original_value = virtual_mode; if (!original_value) virtual_mode = true; balanceLive(now, force, true); virtual_mode = original_value; DebugWrite("virtual live-balance done, proceeding now to flag players that will need moving", 1); /* save the delayed team, and squad for each player */ players = getPlayersProfile(""); /* first need to save daleyed team and squad for the whole list because within move will be checked again if balance is still needed */ players.ForEach(delegate(PlayerProfile pp) { if (pp.getSavedTeamId() >= 0 && pp.getSavedTeamId() != pp.getTeamId()) { /* save the delayed team and squad */ pp.saveDelayedTeamSquad(); /* reset the original team and squad */ pp.setTeamId(pp.getSavedTeamId()); pp.setSquadId(pp.getSavedSquadId()); } pp.resetSavedTeamSquad(); }); /* only now real move or mark */ players.ForEach(delegate(PlayerProfile pp) { if (pp.getDelayedTeamId() > 0 && pp.getDelayedTeamId() != pp.getTeamId()) { if (pp.isAlive()) { DebugWrite("Player ^b" + pp + "^n is alive, flagged for delayed move from ^bTeam(" + TN(pp.getTeamId()) + ").Squad(" + SQN(pp.getSquadId()) + ")^n to ^bDTeam(" + TN(pp.getDelayedTeamId()) + ").DSquad(" + SQN(pp.getDelayedSquadId()) + ")^n", 3); } else { DebugWrite("Player ^b" + pp + "^n " + playerstate2stringED(pp.state) + ", flagged for immediate move from ^bTeam(" + TN(pp.getTeamId()) + ").Squad(" + SQN(pp.getSquadId()) + ")^n to ^bDTeam(" + TN(pp.getDelayedTeamId()) + ").DSquad(" + SQN(pp.getDelayedSquadId()) + ")^n", 3); /* skip balance check, we alreay know teams are not balanced */ /* added by jstmx : Wrong! because amount of marked playes to move can be much more than needed and we have to check balance before every move! */ /* More on this - the teams can still be unbalanced but in other direction because of standart balancer work! So we need check it as well */ // enforceImmediateMove(pp); -- instead we should use delayedMove logic! enforceDelayedMove(pp); } } }); live_balancer = false; }
private object CreateObjectFromNonDefaultConstructor(JsonReader reader, JsonObjectContract contract, ConstructorInfo constructorInfo, string id) { ValidationUtils.ArgumentNotNull(constructorInfo, "constructorInfo"); Type objectType = contract.UnderlyingType; IDictionary<JsonProperty, object> propertyValues = ResolvePropertyAndConstructorValues(contract, reader, objectType); IDictionary<ParameterInfo, object> constructorParameters = constructorInfo.GetParameters().ToDictionary(p => p, p => (object)null); IDictionary<JsonProperty, object> remainingPropertyValues = new Dictionary<JsonProperty, object>(); #if !(UNITY_IPHONE || UNITY_IOS) || (UNITY_IOS && !(UNITY_3_5 || UNITY_4_0_1 || UNITY_4_1 || UNITY_4_2 || UNITY_4_3)) foreach (KeyValuePair<JsonProperty, object> propertyValue in propertyValues) { ParameterInfo matchingConstructorParameter = constructorParameters.ForgivingCaseSensitiveFind(kv => kv.Key.Name, propertyValue.Key.UnderlyingName).Key; if (matchingConstructorParameter != null) constructorParameters[matchingConstructorParameter] = propertyValue.Value; else remainingPropertyValues.Add(propertyValue); } #else propertyValues.ForEach(propertyValue => { ParameterInfo matchingConstructorParameter = constructorParameters.ForgivingCaseSensitiveFind(kv => kv.Key.Name, propertyValue.Key.UnderlyingName).Key; if (matchingConstructorParameter != null) constructorParameters[matchingConstructorParameter] = propertyValue.Value; else remainingPropertyValues.Add(propertyValue); }); #endif object createdObject = constructorInfo.Invoke(constructorParameters.Values.ToArray()); if (id != null) Serializer.ReferenceResolver.AddReference(this, id, createdObject); contract.InvokeOnDeserializing(createdObject, Serializer.Context); #if !(UNITY_IPHONE || UNITY_IOS) || (UNITY_IOS && !(UNITY_3_5 || UNITY_4_0_1 || UNITY_4_1 || UNITY_4_2 || UNITY_4_3)) // go through unused values and set the newly created object's properties foreach (KeyValuePair<JsonProperty, object> remainingPropertyValue in remainingPropertyValues) { JsonProperty property = remainingPropertyValue.Key; object value = remainingPropertyValue.Value; if (ShouldSetPropertyValue(remainingPropertyValue.Key, remainingPropertyValue.Value)) { property.ValueProvider.SetValue(createdObject, value); } else if (!property.Writable && value != null) { // handle readonly collection/dictionary properties JsonContract propertyContract = Serializer.ContractResolver.ResolveContract(property.PropertyType); if (propertyContract is JsonArrayContract) { JsonArrayContract propertyArrayContract = propertyContract as JsonArrayContract; object createdObjectCollection = property.ValueProvider.GetValue(createdObject); if (createdObjectCollection != null) { IWrappedCollection createdObjectCollectionWrapper = propertyArrayContract.CreateWrapper(createdObjectCollection); IWrappedCollection newValues = propertyArrayContract.CreateWrapper(value); foreach (object newValue in newValues) { createdObjectCollectionWrapper.Add(newValue); } } } else if (propertyContract is JsonDictionaryContract) { JsonDictionaryContract jsonDictionaryContract = propertyContract as JsonDictionaryContract; object createdObjectDictionary = property.ValueProvider.GetValue(createdObject); if (createdObjectDictionary != null) { IWrappedDictionary createdObjectDictionaryWrapper = jsonDictionaryContract.CreateWrapper(createdObjectDictionary); IWrappedDictionary newValues = jsonDictionaryContract.CreateWrapper(value); foreach (DictionaryEntry newValue in newValues) { createdObjectDictionaryWrapper.Add(newValue.Key, newValue.Value); } } } } } #else // go through unused values and set the newly created object's properties remainingPropertyValues.ForEach(remainingPropertyValue => { JsonProperty property = remainingPropertyValue.Key; object value = remainingPropertyValue.Value; if (ShouldSetPropertyValue(remainingPropertyValue.Key, remainingPropertyValue.Value)) { property.ValueProvider.SetValue(createdObject, value); } else if (!property.Writable && value != null) { // handle readonly collection/dictionary properties JsonContract propertyContract = Serializer.ContractResolver.ResolveContract(property.PropertyType); if (propertyContract is JsonArrayContract) { JsonArrayContract propertyArrayContract = propertyContract as JsonArrayContract; object createdObjectCollection = property.ValueProvider.GetValue(createdObject); if (createdObjectCollection != null) { IWrappedCollection createdObjectCollectionWrapper = propertyArrayContract.CreateWrapper(createdObjectCollection); IWrappedCollection newValues = propertyArrayContract.CreateWrapper(value); foreach (object newValue in newValues) { createdObjectCollectionWrapper.Add(newValue); } } } else if (propertyContract is JsonDictionaryContract) { JsonDictionaryContract jsonDictionaryContract = propertyContract as JsonDictionaryContract; object createdObjectDictionary = property.ValueProvider.GetValue(createdObject); if (createdObjectDictionary != null) { IWrappedDictionary createdObjectDictionaryWrapper = jsonDictionaryContract.CreateWrapper(createdObjectDictionary); IWrappedDictionary newValues = jsonDictionaryContract.CreateWrapper(value); foreach (DictionaryEntry newValue in newValues) { createdObjectDictionaryWrapper.Add(newValue.Key, newValue.Value); } } } } }); #endif contract.InvokeOnDeserialized(createdObject, Serializer.Context); return createdObject; }