private void AddNewHorse(string selectedHerd, HorseBuilder newHorse) { var newEntity = new HorseEntity { ID = HorseEntity.GenerateNewHorseID(_context), Name = newHorse.Name, Herd = selectedHerd, Age = _newHorse.Age, TakenCareOfBy = newHorse.CaredBy, BrandedFor = newHorse.BrandedBy, FatherName = newHorse.Father, MotherName = newHorse.Mother, Traits = newHorse.Traits, TraitsInspectedAtSkill = newHorse.InspectSkill, IsMale = newHorse.IsMale, PregnantUntil = newHorse.PregnantUntil, SecondaryInfoTagSetter = newHorse.SecondaryInfo }; newEntity.EpicCurve = newHorse.ServerGroup == WurmServer.ServerInfo.ServerGroup.Epic; if (newHorse.ServerGroup == WurmServer.ServerInfo.ServerGroup.Unknown) { Logger.LogError("Adding horse with unknown server group, name: "+newHorse.Name); } _context.InsertHorse(newEntity); _grangerDebug.Log("successfully inserted horse to db"); Popup.Schedule("HORSE ADDED", String.Format("Added new horse to herd {0}: {1}", selectedHerd, newEntity)); }
void AttemptToStartProcessing(string line) { _grangerDebug.Log("attempting to start processing horse due to line: " + line); //clean up if there is still non-timed out process VerifyAndApplyProcessing(); //it is unknown if smiled at horse or something else //attempt to extract the name of game object try { //[20:48:42] You smile at Adolescent diseased Mountainheart. _grangerDebug.Log("extracting object name"); string objectNameWithPrefixes = line.Remove(0, 13).Replace(".", ""); if (!GrangerHelpers.IsBlacklistedCreatureName(objectNameWithPrefixes) && GrangerHelpers.HasAgeInName(objectNameWithPrefixes)) { _grangerDebug.Log("object asumed to be a horse"); var ahSkill = _playerMan.GetAhSkill(); var currentGroup = _playerMan.GetCurrentServerGroup(); if (ahSkill != null && currentGroup != WurmServer.ServerInfo.ServerGroup.Unknown) { _grangerDebug.Log("building new horse object and moving to processor"); _isProcessing = true; _startedProcessingOn = DateTime.Now; _verifyList = new ProcessorVerifyList(); _newHorse = new HorseBuilder { Name = GrangerHelpers.ExtractHorseName(objectNameWithPrefixes), Age = GrangerHelpers.ExtractHorseAge(objectNameWithPrefixes), ServerGroup = currentGroup, InspectSkill = ahSkill.Value, //IsDiseased = // (GrangerHelpers.LineContainsDiseased(objectNameWithPrefixes) != null) }; var fat = GrangerHelpers.LineContainsFat(objectNameWithPrefixes); if (fat != null) _newHorse.SecondaryInfo = HorseEntity.SecondaryInfoTag.Fat; var starving = GrangerHelpers.LineContainsStarving(objectNameWithPrefixes); if (starving != null) _newHorse.SecondaryInfo = HorseEntity.SecondaryInfoTag.Starving; var diseased = GrangerHelpers.LineContainsDiseased(objectNameWithPrefixes); if (diseased != null) _newHorse.SecondaryInfo = HorseEntity.SecondaryInfoTag.Diseased; _verifyList.Name = true; _grangerDebug.Log("finished building"); } else { Popup.Schedule("CAN'T PROCESS HORSE", "Cannot gather data for " + _playerMan.PlayerName + " yet, please try again once Granger fully loads.", 5000); _grangerDebug.Log("processing horse cancelled, still waiting for AH skill or server group searches to finish (skill: " + ahSkill + " ; server group: " + currentGroup); } } else _grangerDebug.Log(objectNameWithPrefixes + " cannot be added. Only named creatures can be added to Granger."); } catch (Exception _e) { //this shouldn't happen, there is always something player is smiling at, unless error happened elsewhere _grangerDebug.Log("! Granger: error while BeginProcessing, event: " + line, true, _e); } }
void VerifyAndApplyProcessing() { if (_newHorse != null) { _grangerDebug.Log("finishing processing horse: " + _newHorse.Name); //verify if enough fields are filled to warrant updating if (_verifyList.IsValid) { _grangerDebug.Log("horse data is valid"); var selectedHerds = GetSelectedHerds(); //string[] herdsToCheck = selectedHerds; var herdsFinds = GetHerdsFinds(selectedHerds, _newHorse.Name); var selectedHerdsFinds = herdsFinds; // if there isn't any horse found in selected herds, // try all herds if setting is set bool allHerdSearch = false; if (herdsFinds.Length == 0 && _parentModule.Settings.Value.DoNotBlockDataUpdateUnlessMultiplesInEntireDb) { allHerdSearch = true; string[] allHerds = GetAllHerds(); herdsFinds = GetHerdsFinds(allHerds, _newHorse.Name); } // first try to update // update only if found exactly one horse if (herdsFinds.Length == 1) { HorseEntity oldHorse = herdsFinds[0]; bool sanityFail = false; #region SANITY_CHECKS //perform sanity checks string sanityFailReason = null; //horses cant suddenly get younger if (oldHorse.Age > _newHorse.Age) { sanityFail = true; if (sanityFailReason == null) sanityFailReason = "New horse data would make the horse younger than it was"; } //basically if both horses HAVE a mother name or father name, they cant have different names //but its entirely possible a mother or father dies and reference is lost, with it the name //no longer is shown, horse appears then as if it had no father or mother //2 cases to check //if current father name is blank, new name can not suddenly hold a name! if (String.IsNullOrEmpty(oldHorse.FatherName) && !String.IsNullOrEmpty(_newHorse.Father)) { sanityFail = true; if (sanityFailReason == null) sanityFailReason = "Old father was blank but new data has a father name"; } //if both names are not blank, then they can't be different! if (!String.IsNullOrEmpty(oldHorse.FatherName) && !String.IsNullOrEmpty(_newHorse.Father) && oldHorse.FatherName != _newHorse.Father) { sanityFail = true; if (sanityFailReason == null) sanityFailReason = "Old data father name was different than new father name"; } //same for mother if (String.IsNullOrEmpty(oldHorse.MotherName) && !String.IsNullOrEmpty(_newHorse.Mother)) { sanityFail = true; if (sanityFailReason == null) sanityFailReason = "Old mother was blank but new data has a mother name"; } if (!String.IsNullOrEmpty(oldHorse.MotherName) && !String.IsNullOrEmpty(_newHorse.Mother) && oldHorse.MotherName != _newHorse.Mother) { sanityFail = true; if (sanityFailReason == null) sanityFailReason = "Old data mother name was different than new mother name"; } //need to compare traits up to lower AH inspect level, //if they mismatch, thats also sanity fail //we should treat null ah inspect value as 0 if (oldHorse.TraitsInspectedAtSkill.HasValue) { //exclude this check if horse had genesis cast within last 1 hour _grangerDebug.Log(string.Format("Checking horse for Genesis cast (horse name: {0}", _newHorse.Name)); if (!_parentModule.Settings.Value.HasGenesisCast(_newHorse.Name)) { _grangerDebug.Log("No genesis cast found"); var lowskill = Math.Min(oldHorse.TraitsInspectedAtSkill.Value, _newHorse.InspectSkill); HorseTrait[] certainTraits = HorseTrait.GetTraitsUpToSkillLevel(lowskill, oldHorse.EpicCurve ?? false); var oldHorseTraits = oldHorse.Traits.ToArray(); var newHorseTraits = _newHorse.Traits.ToArray(); foreach (var trait in certainTraits) { if (oldHorseTraits.Contains(trait) != newHorseTraits.Contains(trait)) { sanityFail = true; if (sanityFailReason == null) sanityFailReason = "Trait mismatch below inspect skill treshhold (" + lowskill + "): " + trait.ToCompactString(); break; } } } else { _grangerDebug.Log("Genesis cast found, skipping trait sanity check"); _parentModule.Settings.Value.RemoveGenesisCast(_newHorse.Name); _grangerDebug.Log(string.Format("Removed cached genesis cast data for {0}", _newHorse.Name)); } } //is new horse server group not within allowed ones? if (_newHorse.ServerGroup == WurmServer.ServerInfo.ServerGroup.Unknown) { sanityFail = true; sanityFailReason = "New horse data had unsupported server group: " + _newHorse.ServerGroup; } //if old horse isEpic != new horse isEpic bool oldIsEpic = oldHorse.EpicCurve ?? false; bool newIsEpic = _newHorse.ServerGroup == WurmServer.ServerInfo.ServerGroup.Epic; if (oldIsEpic != newIsEpic) { sanityFail = true; sanityFailReason = "Old horse is of different server group than current player server group"; } #endregion if (sanityFail) { _grangerDebug.Log("sanity check failed for horse update: " + oldHorse + ". Reason: " + sanityFailReason); Popup.Schedule("COULD NOT UPDATE HORSE", "There was data mismatch when trying to update horse, reason: " + sanityFailReason, 8000); } else { oldHorse.Age = _newHorse.Age; oldHorse.TakenCareOfBy = _newHorse.CaredBy; oldHorse.BrandedFor = _newHorse.BrandedBy; oldHorse.FatherName = _newHorse.Father; oldHorse.MotherName = _newHorse.Mother; if (oldHorse.TraitsInspectedAtSkill <= _newHorse.InspectSkill || _newHorse.InspectSkill > HorseTrait.GetFullTraitVisibilityCap(oldHorse.EpicCurve ?? false)) { oldHorse.Traits = _newHorse.Traits; oldHorse.TraitsInspectedAtSkill = _newHorse.InspectSkill; } else _grangerDebug.Log("old horse data had more accurate trait info, skipping"); oldHorse.SetTag("dead", false); //oldHorse.SetTag("diseased", _newHorse.IsDiseased); oldHorse.SetSecondaryInfoTag(_newHorse.SecondaryInfo); oldHorse.IsMale = _newHorse.IsMale; oldHorse.PregnantUntil = _newHorse.PregnantUntil; _context.SubmitChangesToHorses(); _grangerDebug.Log("successfully updated horse in db"); Popup.Schedule("HORSE UPDATED", String.Format("Updated horse: {0}", oldHorse)); } _newHorse = null; _grangerDebug.Log("processor buffer cleared"); return; // we are done here } // no update performed, try to add bool entireDB = _parentModule.Settings.Value.DoNotBlockDataUpdateUnlessMultiplesInEntireDb; if (selectedHerds.Length == 1 || (entireDB && selectedHerds.Length > 0)) { // can't add a horse if it's already in selected herds // also with entireDB, this will trigger if for some reason 2 or more horses are already in db (update is skipped) if (selectedHerdsFinds.Length == 0) { //do a sanity check to verify this horse name is not in current herd already string herd = selectedHerds[0]; bool exists = _context.Horses.AsEnumerable().Any(x => _newHorse.Name == x.Name && x.Herd == herd); if (!exists) { //add horse AddNewHorse(herd, _newHorse); } else { var message = "Horse with name: " + _newHorse.Name + " already exists in herd: " + herd; Popup.Schedule("CAN'T ADD HORSE", message, 4000); _grangerDebug.Log(message); } _newHorse = null; _grangerDebug.Log("processor buffer cleared"); return; // we are done here } else if (!entireDB) { string message = "Horse with name: " + _newHorse.Name + " already exists in active herd"; Popup.Schedule("CAN'T ADD HORSE", message, 4000); _grangerDebug.Log(message); } } // no update or add performed, figure what went wrong if (herdsFinds.Length > 1) { var partialMessage = allHerdSearch ? "database" : "selected herds"; _grangerDebug.Log("many horses named " + _newHorse.Name + " found in " + partialMessage + ", add/update aborted"); Popup.Schedule("CAN'T ADD OR UPDATE HORSE", partialMessage + " contain many horses named " + _newHorse.Name + ", narrow herd selection", 6000); //notify user to narrow the herd selection } else if (!entireDB && (selectedHerds.Length == 0 || selectedHerds.Length > 1)) { const string message = "exactly one herd has to be active to add new horse"; _grangerDebug.Log(message); Popup.Schedule("CAN'T ADD OR UPDATE HORSE", message, 4000); } else if (entireDB && selectedHerds.Length == 0) { const string message = "at least one herd must be select to add new horse"; _grangerDebug.Log(message); Popup.Schedule("CAN'T ADD OR UPDATE HORSE", message, 4000); } else { //shield against any possibly missed situations const string message = "add/update horse failed for unknown reasons"; _grangerDebug.Log(message); Logger.LogError(message, this); Popup.Schedule("CAN'T ADD OR UPDATE HORSE", message, 4000); } } else { _grangerDebug.Log("horse data was invalid, data: " + GetVerifyListData(_verifyList)); } //clear the buffer _newHorse = null; _grangerDebug.Log("processor buffer cleared"); } }