private static bool TransferChecks(int userId, UserSpaceObject sender, UserSpaceObject receiver, Transfer transfer, Ship senderShip, Ship targetShip, Colony senderColony, Colony targetColony) { //check that sender is ownder by user if (sender.GetUserId() != userId) return false; var SenderUser = Core.Instance.users[sender.GetUserId()]; var ReceiverUser = Core.Instance.users[receiver.GetUserId()]; //check that one does not move cargo from a neutral (0) space station (hullId 201) if (sender is Ship) { var SendShip = (Ship)sender; if (SendShip.hullid == 201 && SendShip.userid == 0) return false; } if (receiver is Ship) { var RecShip = (Ship)receiver; if (RecShip.hullid == 201 && RecShip.userid == 0) return false; } //test if goods are sent or received: if (transfer.Goods.Count == 0) return false; var send = false; var receive = false; receive = (transfer.Goods.Any(e => e.Qty < 0)); send = (transfer.Goods.Any(e => e.Qty > 0)); if (!send && !receive) return false; //if trade is between users, and goods are received, check that they are at war if (receive && sender.GetUserId() != receiver.GetUserId() && receiver.GetUserId() != 0) { Relation CurrentRelation = Core.Instance.userRelations.getRelation(SenderUser, ReceiverUser); if (SenderUser.allianceId == ReceiverUser.allianceId) CurrentRelation = Relation.AllianceMember; //check that both are enemies (or player 0 is involved) if (receive && CurrentRelation != Relation.War && CurrentRelation != Relation.AllianceMember) { return false; } } //test that both are on the same field (if it is not scrap or recycle= if (transfer.Target > 0) { Field SenderField = null; Tuple<byte, byte> SenderSystemXY = null; if (senderShip != null) { SenderField = senderShip.field; SenderSystemXY = senderShip.getSystemCoords(); } if (senderColony != null) { SenderField = senderColony.field; SenderSystemXY = senderColony.systemXY(); } Field TargetField = null; Tuple<byte, byte> TargetSystemXY = null; if (targetShip != null) { TargetField = targetShip.field; TargetSystemXY = targetShip.getSystemCoords(); } if (targetColony != null) { TargetField = targetColony.field; TargetSystemXY = targetColony.systemXY(); } if (SenderField != TargetField) return false; if (SenderSystemXY != null && TargetSystemXY == null) return false; if (SenderSystemXY == null && TargetSystemXY != null) return false; if (SenderSystemXY != null && (SenderSystemXY.Item1 != TargetSystemXY.Item1 || SenderSystemXY.Item2 != TargetSystemXY.Item2)) return false; } //tests that all goods are in store on both sides of the transfer List<SpaceObjectStock> SenderStock = null; List<SpaceObjectStock> TargetStock = null; if (senderShip != null) SenderStock = senderShip.goods.ToList<SpaceObjectStock>(); if (targetShip != null) TargetStock = targetShip.goods.ToList<SpaceObjectStock>(); if (senderColony != null) SenderStock = senderColony.goods.ToList<SpaceObjectStock>(); if (targetColony != null) TargetStock = targetColony.goods.ToList<SpaceObjectStock>(); int TransferCapacity = 0; foreach (var transferLine in transfer.Goods){ var Good = Core.Instance.Goods[transferLine.Id]; TransferCapacity += Good.Weight() * transferLine.Qty; if (transferLine.Qty > 0) { //check that sender has it on store if (!SenderStock.Any(e => e.goodsId == transferLine.Id && e.amount >= transferLine.Qty)) return false; } else { //check that target has it on store if (!TargetStock.Any(e => e.goodsId == transferLine.Id && e.amount >= -transferLine.Qty)) return false; } } //test that scrap or recycle does not demand something in return. transfer can be sent to user 0 -> that will always be a scrap or recycle command if (receiver.GetUserId() == 0 && ( receiver.Id == 0 || receiver.Id == -1) ) { if (receive) return false; } //sender + receiver : sufficient cargoSpace if (TransferCapacity < 0) { int RemainigFreeSpace = sender.CalcStorage() - sender.AmountOnStock(); //check SenderStock: if (RemainigFreeSpace < -TransferCapacity) return false; } else { if (receiver.GetUserId() != 0) { int RemainigFreeSpace = receiver.CalcStorage() - receiver.AmountOnStock(); //check ReceiverStock: if (RemainigFreeSpace < TransferCapacity) return false; } } return true; }
//similar to Ship.createSpaceStation(), but not easily generalizable public bool build2(int shipTemplateId, int _userId, int _colonyId, bool fastBuild, ref int newShipId, ref ShipBuildErrorCode errorCode, ref int errorValue) { Core core = Core.Instance; GalaxyMap galaxyMap = null; // lock colony and field Colony colony = core.colonies[_colonyId]; if (colony == null) { return(false); } if (colony.userId != _userId) { return(false); } Field field = colony.field; ShipTemplate template = core.shipTemplate[shipTemplateId]; if (!(this.checkFreeOrbit(field, _userId, colony.systemXY(), ref errorCode, ref errorValue) && this.checkGoodsAvailability(colony, template, fastBuild, ref errorCode, ref errorValue) && this.checkSpaceport(colony, ref errorCode, ref errorValue) && this.checkTechnology(template, _userId, fastBuild, ref errorCode, ref errorValue) && this.checkUniqueness(field, template, colony.systemXY(), ref errorCode, ref errorValue))) { return(false); } //Lock List <Lockable> elementsToLock = new List <Lockable>(3); elementsToLock.Add(colony); elementsToLock.Add(field); //check for transcendence //ToDo: replace 220 with a sql data field if (template.hullid == 220 && core.GalaxyMap.transcendenceRequirement == 0) { galaxyMap = core.GalaxyMap; elementsToLock.Add(galaxyMap); } if (!LockingManager.lockAllOrSleep(elementsToLock)) { return(false); } newShipId = (int)Core.Instance.identities.shipLock.getNext(); try { //all checks again inside of lock if (!(this.checkFreeOrbit(field, _userId, colony.systemXY(), ref errorCode, ref errorValue) && this.checkGoodsAvailability(colony, template, fastBuild, ref errorCode, ref errorValue) && this.checkSpaceport(colony, ref errorCode, ref errorValue) && this.checkTechnology(template, _userId, fastBuild, ref errorCode, ref errorValue) && this.checkUniqueness(field, template, colony.systemXY(), ref errorCode, ref errorValue))) { return(false); } //everything checked and locked //now do the work Ship newShip = buildShip(newShipId, template, field, _userId, colony, fastBuild); newShip.SetTranscension(galaxyMap); //write SQL Core.Instance.dataConnection.insertShip(newShip); Core.Instance.dataConnection.saveColonyGoods(colony); } catch (Exception ex) { SpacegameServer.Core.Core.Instance.writeExceptionToLog(ex); } finally { //release the ressources LockingManager.unlockAll(elementsToLock); } return(true); }