diff --git a/src/Perpetuum.Bootstrapper/PerpetuumBootstrapper.cs b/src/Perpetuum.Bootstrapper/PerpetuumBootstrapper.cs index fcfa664a0..dc860a872 100644 --- a/src/Perpetuum.Bootstrapper/PerpetuumBootstrapper.cs +++ b/src/Perpetuum.Bootstrapper/PerpetuumBootstrapper.cs @@ -596,6 +596,11 @@ private void InitRelayManager() }); _ = _builder.RegisterType(); _ = _builder.RegisterType(); + + _ = _builder.RegisterType().SingleInstance().AutoActivate().OnActivated(e => + { + e.Context.Resolve().AddProcess(e.Instance.ToAsync().AsTimed(TimeSpan.FromMinutes(1))); + }); } private IRegistrationBuilder diff --git a/src/Perpetuum/Modules/DrillerModule.cs b/src/Perpetuum/Modules/DrillerModule.cs index 914b46524..2c091b19b 100644 --- a/src/Perpetuum/Modules/DrillerModule.cs +++ b/src/Perpetuum/Modules/DrillerModule.cs @@ -173,6 +173,13 @@ remoteControlledCreature.CommandRobot is Player ownerPlayer Debug.Assert(player != null, "player != null"); foreach (ItemInfo material in extractedMaterials) { + Db.Query() + .CommandText("exec sp_RecordResourceGathered @gathered_on, @resource_name, @quantity") + .SetParameter("@gathered_on", DateTime.UtcNow) + .SetParameter("@resource_name", material.EntityDefault.Name) + .SetParameter("@quantity", material.Quantity) + .ExecuteNonQuery(); + Item item = (Item)Factory.CreateWithRandomEID(material.Definition); item.Owner = Owner; diff --git a/src/Perpetuum/Modules/HarvesterModule.cs b/src/Perpetuum/Modules/HarvesterModule.cs index 4b074e7f1..898c05e1d 100644 --- a/src/Perpetuum/Modules/HarvesterModule.cs +++ b/src/Perpetuum/Modules/HarvesterModule.cs @@ -127,8 +127,16 @@ remoteControlledCreature.CommandRobot is Player ownerPlayer : ParentRobot as Player; Debug.Assert(player != null, "player != null"); + foreach (ItemInfo extractedMaterial in harvestedPlants) { + Db.Query() + .CommandText("exec sp_RecordResourceGathered @gathered_on, @resource_name, @quantity") + .SetParameter("@gathered_on", DateTime.UtcNow) + .SetParameter("@resource_name", extractedMaterial.EntityDefault.Name) + .SetParameter("@quantity", extractedMaterial.Quantity) + .ExecuteNonQuery(); + Item item = (Item)Factory.CreateWithRandomEID(extractedMaterial.Definition); item.Owner = Owner; item.Quantity = extractedMaterial.Quantity; diff --git a/src/Perpetuum/Modules/LargeDrillerModule.cs b/src/Perpetuum/Modules/LargeDrillerModule.cs index 94897fdda..a07b08dbb 100644 --- a/src/Perpetuum/Modules/LargeDrillerModule.cs +++ b/src/Perpetuum/Modules/LargeDrillerModule.cs @@ -9,6 +9,7 @@ using Perpetuum.Zones.Terrains; using Perpetuum.Zones.Terrains.Materials; using Perpetuum.Zones.Terrains.Materials.Minerals; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -59,6 +60,7 @@ public override void DoExtractMinerals(IZone zone) extractedMaterials .AddRange(RareMaterialHandler.GenerateRareMaterials(materialInfo.EntityDefault.Definition)); + CreateBeam(position.Center, BeamState.AlignToTerrain); using (TransactionScope scope = Db.CreateTransaction()) { @@ -70,6 +72,13 @@ public override void DoExtractMinerals(IZone zone) Debug.Assert(player != null, "player != null"); foreach (ItemInfo material in extractedMaterials) { + Db.Query() + .CommandText("exec sp_RecordResourceGathered @gathered_on, @resource_name, @quantity") + .SetParameter("@gathered_on", DateTime.UtcNow) + .SetParameter("@resource_name", material.EntityDefault.Name) + .SetParameter("@quantity", material.Quantity) + .ExecuteNonQuery(); + Item item = (Item)Factory.CreateWithRandomEID(material.Definition); item.Owner = Owner; item.Quantity = material.Quantity; diff --git a/src/Perpetuum/Modules/LargeHarvesterModule.cs b/src/Perpetuum/Modules/LargeHarvesterModule.cs index 55f5c6a88..10045ab18 100644 --- a/src/Perpetuum/Modules/LargeHarvesterModule.cs +++ b/src/Perpetuum/Modules/LargeHarvesterModule.cs @@ -10,6 +10,7 @@ using Perpetuum.Zones.Terrains; using Perpetuum.Zones.Terrains.Materials.Plants; using Perpetuum.Zones.Terrains.Materials.Plants.Harvesters; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -68,8 +69,16 @@ remoteControlledCreature.CommandRobot is Player ownerPlayer : ParentRobot as Player; Debug.Assert(player != null, "player != null"); + foreach (ItemInfo extractedMaterial in harvestedPlants) { + Db.Query() + .CommandText("exec sp_RecordResourceGathered @gathered_on, @resource_name, @quantity") + .SetParameter("@gathered_on", DateTime.UtcNow) + .SetParameter("@resource_name", extractedMaterial.EntityDefault.Name) + .SetParameter("@quantity", extractedMaterial.Quantity) + .ExecuteNonQuery(); + Item item = (Item)Factory.CreateWithRandomEID(extractedMaterial.Definition); item.Owner = Owner; item.Quantity = extractedMaterial.Quantity; diff --git a/src/Perpetuum/Perpetuum.csproj b/src/Perpetuum/Perpetuum.csproj index 9d0721ed1..c649304bc 100644 --- a/src/Perpetuum/Perpetuum.csproj +++ b/src/Perpetuum/Perpetuum.csproj @@ -425,6 +425,7 @@ + diff --git a/src/Perpetuum/Services/Looting/LootContainer.cs b/src/Perpetuum/Services/Looting/LootContainer.cs index 7195ddea9..638deca36 100644 --- a/src/Perpetuum/Services/Looting/LootContainer.cs +++ b/src/Perpetuum/Services/Looting/LootContainer.cs @@ -1,19 +1,11 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Transactions; using Perpetuum.Accounting.Characters; using Perpetuum.Builders; using Perpetuum.Common.Loggers.Transaction; using Perpetuum.Data; using Perpetuum.EntityFramework; using Perpetuum.ExportedTypes; - using Perpetuum.Groups.Gangs; using Perpetuum.Items; -using Perpetuum.Log; using Perpetuum.Players; using Perpetuum.Players.ExtensionMethods; using Perpetuum.Robots; @@ -22,6 +14,12 @@ using Perpetuum.Units; using Perpetuum.Zones; using Perpetuum.Zones.Beams; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Transactions; namespace Perpetuum.Services.Looting { @@ -29,7 +27,7 @@ public class LootContainer : Unit { public static readonly TimeSpan DespawnTime = TimeSpan.FromMinutes(15); - private readonly ConcurrentDictionary _pinTryCounts = new ConcurrentDictionary(); + private readonly ConcurrentDictionary _pinTryCounts = new ConcurrentDictionary(); private const int LOOT_RANGE = 10; private UnitDespawnHelper _despawnHelper; @@ -54,26 +52,24 @@ public LootContainer(ILootItemRepository lootItemRepository) public void SetDespawnTime(TimeSpan despawnTime) { - _despawnHelper = UnitDespawnHelper.Create(this,despawnTime); + _despawnHelper = UnitDespawnHelper.Create(this, despawnTime); _despawnHelper.CanApplyDespawnEffect = OnCanApplyDespawnEffect; } public override void AcceptVisitor(IEntityVisitor visitor) { if (!TryAcceptVisitor(this, visitor)) + { base.AcceptVisitor(visitor); + } } public int PinCode { - protected get { return _pinCode.Value;} - set { _pinCode.Value = value; } + protected get => _pinCode.Value; set => _pinCode.Value = value; } - public override ErrorCodes IsAttackable - { - get { return ErrorCodes.TargetIsNonAttackable; } - } + public override ErrorCodes IsAttackable => ErrorCodes.TargetIsNonAttackable; private bool OnCanApplyDespawnEffect(Unit unit) { @@ -87,7 +83,7 @@ public IEnumerable GetLootItems() public void AddLoots(IEnumerable items) { - foreach (var item in items) + foreach (LootItem item in items) { AddLoot(item); } @@ -95,17 +91,19 @@ public void AddLoots(IEnumerable items) protected void AddLoot(LootItem item) { - if ( item.Quantity == 0 ) + if (item.Quantity == 0) + { return; + } - _itemRepository.AddWithStack(this,item); + _itemRepository.AddWithStack(this, item); } public void SendLootListToPlayer(Player player, int pinCode) { - HasAccess(player,pinCode); + HasAccess(player, pinCode); - Zone.CreateBeam(BeamType.loot_bolt,b => b.WithSource(player) + Zone.CreateBeam(BeamType.loot_bolt, b => b.WithSource(player) .WithTarget(this) .WithState(BeamState.Hit).WithDuration(1000)); player.Session.SendPacket(_lootListPacketBuilder); @@ -117,26 +115,30 @@ protected virtual void HasAccess(Player looter, int pinCode) { IsInLootRange(looter).ThrowIfFalse(ErrorCodes.LootContainerOutOfRange); - var owner = this.GetOwnerAsCharacter(); - + Character owner = this.GetOwnerAsCharacter(); + if (owner == Character.None || // van owner? owner == looter.Character || // ugyanaz akar-e lootolni aki a gazdi Gang.CompareGang(looter.Character, owner) // ugyanabban a gangben vannak-e ) + { return; + } if (!IsFieldContainer() && !looter.IsInDefaultCorporation()) { if (looter.CorporationEid == owner.CorporationEid) + { return; + } } - CheckPinCode(looter.Character,pinCode); + CheckPinCode(looter.Character, pinCode); } private bool IsInLootRange(Player player) { return IsInRangeOf3D(player, LOOT_RANGE); } - private void CheckPinCode(Character looter,int pinCode) + private void CheckPinCode(Character looter, int pinCode) { _pinTryCounts.GetOrDefault(looter).ThrowIfGreaterOrEqual(3, ErrorCodes.AccessDenied); @@ -172,7 +174,7 @@ public void TakeLoots(Player player, int pinCode, IList> lock (syncObject) { - var takeLootBeamBuilder = Beam.NewBuilder().WithType(BeamType.loot_bolt) + BeamBuilder takeLootBeamBuilder = Beam.NewBuilder().WithType(BeamType.loot_bolt) .WithSource(player) .WithTarget(this) .WithState(BeamState.Hit) @@ -180,38 +182,42 @@ public void TakeLoots(Player player, int pinCode, IList> Zone.CreateBeam(takeLootBeamBuilder); - using (var scope = Db.CreateTransaction()) + using (TransactionScope scope = Db.CreateTransaction()) { - var container = player.GetContainer(); + RobotInventory container = player.GetContainer(); Debug.Assert(container != null, "container != null"); container.EnlistTransaction(); - var lootedItems = new List(); + List lootedItems = new List(); - var progressPacketBuilder = new LootContainerProgressInfoPacketBuilder(container, this, items.Count); + LootContainerProgressInfoPacketBuilder progressPacketBuilder = new LootContainerProgressInfoPacketBuilder(container, this, items.Count); - foreach (var kvp in items) + foreach (KeyValuePair kvp in items) { try { - var lootId = kvp.Key; - var reqQty = kvp.Value; + Guid lootId = kvp.Key; + int reqQty = kvp.Value; - var lootItem = _itemRepository.Get(this, lootId); + LootItem lootItem = _itemRepository.Get(this, lootId); if (lootItem == null) + { continue; + } if (lootItem.Quantity < reqQty) { reqQty = lootItem.Quantity; } - var item = CreateWithRandomEid(lootItem.ItemInfo); + Item item = CreateWithRandomEid(lootItem.ItemInfo); item.Owner = player.Owner; item.Quantity = reqQty; item.IsRepackaged = lootItem.ItemInfo.IsRepackaged; if (!container.IsEnoughCapacity(item)) + { continue; + } //ha serult akkor legyen serult item.Health = lootItem.ItemInfo.Health; @@ -224,9 +230,13 @@ public void TakeLoots(Player player, int pinCode, IList> lootItem.Quantity -= reqQty; if (lootItem.Quantity <= 0) - _itemRepository.Delete(this,lootItem); + { + _itemRepository.Delete(this, lootItem); + } else - _itemRepository.Update(this,lootItem); + { + _itemRepository.Update(this, lootItem); + } lootedItems.Add(item); } @@ -264,25 +274,27 @@ public void TakeLoots(Player player, int pinCode, IList> private void OnTakeLoots(Player player, IEnumerable lootedItems) { - var b = TransactionLogEvent.Builder().SetTransactionType(TransactionType.TakeLoot).SetCharacter(player.Character).SetContainer(Eid); + TransactionLogEventBuilder b = TransactionLogEvent.Builder().SetTransactionType(TransactionType.TakeLoot).SetCharacter(player.Character).SetContainer(Eid); - var displayOrder = GetMissionDisplayOrder(); - var missionGuid = GetMissionGuid(); + int displayOrder = GetMissionDisplayOrder(); + Guid missionGuid = GetMissionGuid(); - foreach (var item in lootedItems) + foreach (Item item in lootedItems) { b.SetItem(item); player.Character.LogTransaction(b); if (this is FieldContainer) + { continue; + } + + //#if DEBUG + // Logger.Info(">>>>> ENQUEUE LOOTING >>>>> " + player.Character.Id + " " + item.ED.Name + " qty:" + item.Quantity); + //#endif -#if DEBUG - Logger.Info(">>>>> ENQUEUE LOOTING >>>>> " + player.Character.Id + " " + item.ED.Name + " qty:" + item.Quantity); -#endif + player.MissionHandler.EnqueueMissionEventInfo(new LootMissionEventInfo(player, item, CurrentPosition, missionGuid, displayOrder)); - player.MissionHandler.EnqueueMissionEventInfo(new LootMissionEventInfo(player,item,CurrentPosition,missionGuid,displayOrder)); - } } @@ -299,23 +311,29 @@ protected override void OnUpdate(TimeSpan time) _despawnHelper.Update(time, this); if (IsFieldContainer()) + { return; + } _timerResetOwner.Update(time); if (_timerResetOwner.Passed) + { ResetOwner(); + } } private void ResetOwner() { - if ( Owner == 0L ) + if (Owner == 0L) + { return; + } Db.CreateTransactionAsync(scope => { Owner = 0; - this.Save(); + Save(); }); } @@ -325,7 +343,8 @@ protected override void OnRemovedFromZone(IZone zone) { _itemRepository.DeleteAll(this); zone.UnitService.RemoveUserUnit(this); - }).ContinueWith(t => { + }).ContinueWith(t => + { base.OnRemovedFromZone(zone); }); } @@ -346,7 +365,7 @@ public LootContainerProgressInfoPacketBuilder(RobotInventory robotInventory, Loo public Packet Build() { - var packet = new Packet(ZoneCommand.LootContainerProgressInfo); + Packet packet = new Packet(ZoneCommand.LootContainerProgressInfo); packet.AppendLong(_robotInventory.Eid); packet.AppendLong(_container.Eid); @@ -375,14 +394,14 @@ public LootListPacketBuilder(LootContainer container, ILootItemRepository itemRe public Packet Build() { - var packet = new Packet(ZoneCommand.LootList); + Packet packet = new Packet(ZoneCommand.LootList); packet.AppendLong(_container.Eid); - var loots = _itemRepository.GetAll(_container).ToList(); + List loots = _itemRepository.GetAll(_container).ToList(); packet.AppendInt(loots.Count); - foreach (var lootItem in loots) + foreach (LootItem lootItem in loots) { lootItem.AppendToPacket(packet); } @@ -400,13 +419,10 @@ private class Looters public Looters(LootContainer lootContainer) { _lootContainer = lootContainer; - _action = new TimerAction(CleanUpLooters,TimeSpan.FromSeconds(1000)); + _action = new TimerAction(CleanUpLooters, TimeSpan.FromSeconds(1000)); } - public int Count - { - get { return _looters.Count; } - } + public int Count => _looters.Count; public IEnumerable GetLooters() { @@ -430,14 +446,16 @@ public void Update(TimeSpan time) private void CleanUpLooters() { - foreach (var kvp in _looters) + foreach (KeyValuePair kvp in _looters) { - var player = kvp.Value; - var isInZone = player.InZone; - var isInLootRange = _lootContainer.IsInLootRange(player); + Player player = kvp.Value; + bool isInZone = player.InZone; + bool isInLootRange = _lootContainer.IsInLootRange(player); if (isInZone && isInLootRange) + { continue; + } _looters.Remove(kvp.Key); } @@ -529,20 +547,24 @@ public LootContainerBuilder AddLoot(LootItem lootItem) public LootContainer BuildAndAddToZone(IZone zone, Position position) { if (_lootItems.Count == 0) + { return null; + } - var container = Build(zone, position); + LootContainer container = Build(zone, position); if (container == null) + { return null; + } Transaction.Current.OnCommited(() => { - var beamBuilder = Beam.NewBuilder().WithType(_enterBeamType).WithSource(_ownerPlayer) + BeamBuilder beamBuilder = Beam.NewBuilder().WithType(_enterBeamType).WithSource(_ownerPlayer) .WithTarget(container) .WithState(BeamState.Hit) .WithDuration(TimeSpan.FromSeconds(5)); - container.AddToZone(zone,position,ZoneEnterType.Default, beamBuilder); + container.AddToZone(zone, position, ZoneEnterType.Default, beamBuilder); }); return container; @@ -551,26 +573,69 @@ public LootContainer BuildAndAddToZone(IZone zone, Position position) [CanBeNull] public LootContainer Build(IZone zone, Position position) { - var definitionName = _containerTypeToName.GetOrDefault(_containerType); - var container = (LootContainer)CreateUnitWithRandomEID(definitionName); + string definitionName = _containerTypeToName.GetOrDefault(_containerType); + LootContainer container = (LootContainer)CreateUnitWithRandomEID(definitionName); if (container == null) + { return null; + } container.PinCode = _pinCode; if (_ownerPlayer != null) + { container.Owner = _ownerPlayer.Owner; + } container.Initialize(); container.AddLoots(_lootItems.Where(l => !l.ItemInfo.IsRepackaged)); - var stackedLoots = _lootItems.Where(l => l.ItemInfo.IsRepackaged) + IEnumerable stackedLoots = _lootItems.Where(l => l.ItemInfo.IsRepackaged) .GroupBy(l => l.ItemInfo.Definition) .Select(grp => LootItemBuilder.Create(grp.Key).AsRepackaged().SetQuantity(grp.Sum(l => l.Quantity)).Build()); container.AddLoots(stackedLoots); - zone.UnitService.AddUserUnit(container,position); + + IEnumerable> plasmaByType = container + .GetLootItems() + .Where(x => x.ItemInfo.EntityDefault.CategoryFlags.IsCategory(CategoryFlags.cf_reactor_plasma)) + .GroupBy(x => x.ItemInfo.EntityDefault.Name); + + foreach (IGrouping plasma in plasmaByType) + { + using (TransactionScope scope = Db.CreateTransaction()) + { + Db.Query() + .CommandText("exec sp_RecordPlasmaGathered @gathered_on, @plasma_type, @quantity") + .SetParameter("@gathered_on", DateTime.UtcNow) + .SetParameter("@plasma_type", plasma.Key) + .SetParameter("@quantity", plasma.Sum(x => x.ItemInfo.Quantity)) + .ExecuteNonQuery(); + scope.Complete(); + } + } + + IEnumerable> fragmentsByType = container + .GetLootItems() + .Where(x => x.ItemInfo.EntityDefault.CategoryFlags.IsAny(new CategoryFlags[] { CategoryFlags.cf_robotshards, CategoryFlags.cf_research_kits, CategoryFlags.cf_reactor_cores })) + .GroupBy(x => x.ItemInfo.EntityDefault.Name); + + foreach (IGrouping fragment in fragmentsByType) + { + using (TransactionScope scope = Db.CreateTransaction()) + { + Db.Query() + .CommandText("exec sp_RecordResourceGathered @gathered_on, @resource_name, @quantity") + .SetParameter("@gathered_on", DateTime.UtcNow) + .SetParameter("@resource_name", fragment.Key) + .SetParameter("@quantity", fragment.Sum(x => x.ItemInfo.Quantity)) + .ExecuteNonQuery(); + scope.Complete(); + } + } + + zone.UnitService.AddUserUnit(container, position); return container; } } diff --git a/src/Perpetuum/Services/MarketEngine/Market.cs b/src/Perpetuum/Services/MarketEngine/Market.cs index 943134fb5..aab963ec6 100644 --- a/src/Perpetuum/Services/MarketEngine/Market.cs +++ b/src/Perpetuum/Services/MarketEngine/Market.cs @@ -1,8 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Transactions; using Perpetuum.Accounting.Characters; using Perpetuum.Common; using Perpetuum.Common.Loggers.Transaction; @@ -10,7 +5,6 @@ using Perpetuum.Data; using Perpetuum.EntityFramework; using Perpetuum.ExportedTypes; - using Perpetuum.Groups.Corporations; using Perpetuum.Items; using Perpetuum.Log; @@ -18,6 +12,11 @@ using Perpetuum.Units.DockingBases; using Perpetuum.Zones; using Perpetuum.Zones.PBS.DockingBases; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Transactions; namespace Perpetuum.Services.MarketEngine { @@ -34,7 +33,7 @@ public class Market : Entity private readonly ICentralBank _centralBank; private readonly DockingBaseHelper _dockingBaseHelper; - public Market(MarketHelper marketHelper,IMarketOrderRepository orderRepository,MarketHandler marketHandler,MarketOrder.Factory marketOrderFactory,IEntityServices entityServices,ICentralBank centralBank,DockingBaseHelper dockingBaseHelper) + public Market(MarketHelper marketHelper, IMarketOrderRepository orderRepository, MarketHandler marketHandler, MarketOrder.Factory marketOrderFactory, IEntityServices entityServices, ICentralBank centralBank, DockingBaseHelper dockingBaseHelper) { _marketHelper = marketHelper; _orderRepository = orderRepository; @@ -48,12 +47,12 @@ public Market(MarketHelper marketHelper,IMarketOrderRepository orderRepository,M [NotNull] public Item GetItemByMarketOrder(MarketOrder marketOrder) { - if ( marketOrder.itemEid == null) + if (marketOrder.itemEid == null) throw new PerpetuumException(ErrorCodes.ServerError); // load market entity - var itemOnMarket = Item.GetOrThrow((long) marketOrder.itemEid); - itemOnMarket.Parent.ThrowIfNotEqual(Eid,ErrorCodes.AccessDenied); + var itemOnMarket = Item.GetOrThrow((long)marketOrder.itemEid); + itemOnMarket.Parent.ThrowIfNotEqual(Eid, ErrorCodes.AccessDenied); return itemOnMarket; } @@ -66,7 +65,7 @@ public DockingBase GetDockingBase() [NotNull] public static Market GetOrThrow(long marketEid) { - return (Market) Repository.Load(marketEid).ThrowIfNull(ErrorCodes.MarketNotFound); + return (Market)Repository.Load(marketEid).ThrowIfNull(ErrorCodes.MarketNotFound); } public int GetItemsCount() @@ -206,8 +205,8 @@ public MarketOrder CreateBuyOrder(Character buyer, int itemDefinition, int durat private double Tax { - get { return GetTax(); } - set { StoreTax(value); } + get { return GetTax(); } + set { StoreTax(value); } } private double GetTax() @@ -242,9 +241,9 @@ public void SetTax(Character character, double newTax) IsPlayerControlledMarketTax().ThrowIfFalse(ErrorCodes.AccessDenied); var oldTax = Tax; - + newTax = newTax.Clamp(); - + var coporationEid = character.CorporationEid; ProfitingOwnerSelector.GetProfitingOwner(GetDockingBase()).ThrowIfNull(ErrorCodes.AccessDenied); @@ -252,8 +251,8 @@ public void SetTax(Character character, double newTax) var corporation = PrivateCorporation.GetOrThrow(coporationEid); var role = corporation.GetMemberRole(character); - role.IsAnyRole(CorporationRole.CEO, CorporationRole.DeputyCEO, CorporationRole.Accountant ).ThrowIfFalse(ErrorCodes.InsufficientPrivileges); - + role.IsAnyRole(CorporationRole.CEO, CorporationRole.DeputyCEO, CorporationRole.Accountant).ThrowIfFalse(ErrorCodes.InsufficientPrivileges); + //write log var e = new MarketTaxChangeLogEvent { @@ -265,7 +264,7 @@ public void SetTax(Character character, double newTax) }; GetTaxChangeLogger().Log(e); - + //set value Tax = newTax; } @@ -288,7 +287,7 @@ public void AddCentralBank(TransactionType transactionType, double amount) if (IsOnTrainingZone()) return; - _centralBank.AddAmount(amount,transactionType); + _centralBank.AddAmount(amount, transactionType); } public void ForceInsertAveragePrice(int itemDefinition, double price, int quantity, DateTime dateTime) @@ -316,7 +315,7 @@ public void InsertStatsForPeriod(int days, double price, int amount, int definit public Dictionary GetAverageHistory(int day, int itemDefinition) { - var startDate = DateTime.Today.AddDays(-1*day); + var startDate = DateTime.Today.AddDays(-1 * day); var count = 0; var prices = Db.Query().CommandText(@"select totalprice / quantity as price,date,dailyhighest,dailylowest,quantity from @@ -328,7 +327,7 @@ marketaverageprices where .SetParameter("@itemDefinition", itemDefinition) .SetParameter("@day", day) .SetParameter("@startDate", startDate) - .Execute().Select(r => (object) new Dictionary + .Execute().Select(r => (object)new Dictionary { {k.price, r.GetValue(0)}, {k.date, r.GetValue(1)}, @@ -416,7 +415,7 @@ public void FulfillBuyOrderInstantly(Character buyer, bool useBuyerCorporationWa _marketHelper.CashIn(buyer, useBuyerCorporationWallet, marketSellOrder.price, marketSellOrder.itemDefinition, quantity, TransactionType.marketBuy); //pay out - this.PayOutToSeller(seller,marketSellOrder.useCorporationWallet,itemOnMarket.Definition,marketSellOrder.price,quantity,TransactionType.marketSell,marketSellOrder.IsAffectsAverage(),forCorporation); + this.PayOutToSeller(seller, marketSellOrder.useCorporationWallet, itemOnMarket.Definition, marketSellOrder.price, quantity, TransactionType.marketSell, marketSellOrder.IsAffectsAverage(), forCorporation); } else if (itemOnMarket.Quantity == quantity) { @@ -433,7 +432,7 @@ public void FulfillBuyOrderInstantly(Character buyer, bool useBuyerCorporationWa _marketHelper.CashIn(buyer, useBuyerCorporationWallet, marketSellOrder.price, marketSellOrder.itemDefinition, quantity, TransactionType.marketBuy); //pay out - this.PayOutToSeller(seller,marketSellOrder.useCorporationWallet,itemOnMarket.Definition,marketSellOrder.price,quantity,TransactionType.marketSell,marketSellOrder.IsAffectsAverage(),forCorporation); + this.PayOutToSeller(seller, marketSellOrder.useCorporationWallet, itemOnMarket.Definition, marketSellOrder.price, quantity, TransactionType.marketSell, marketSellOrder.IsAffectsAverage(), forCorporation); marketSellOrder.quantity = 0; //signal the sell order delete to the client } @@ -459,7 +458,7 @@ public void FulfillBuyOrderInstantly(Character buyer, bool useBuyerCorporationWa AddCentralBank(TransactionType.buyOrderDeposit, pricePerPiece * (quantity - itemOnMarket.Quantity)); //pay out for the current market item - this.PayOutToSeller(seller,marketSellOrder.useCorporationWallet,itemOnMarket.Definition,marketSellOrder.price,itemOnMarket.Quantity,TransactionType.marketSell,marketSellOrder.IsAffectsAverage(),forCorporation); + this.PayOutToSeller(seller, marketSellOrder.useCorporationWallet, itemOnMarket.Definition, marketSellOrder.price, itemOnMarket.Quantity, TransactionType.marketSell, marketSellOrder.IsAffectsAverage(), forCorporation); marketSellOrder.quantity = 0; //signal to the client @@ -472,7 +471,7 @@ public void FulfillBuyOrderInstantly(Character buyer, bool useBuyerCorporationWa .Send(); } - Market.SendMarketItemBoughtMessage(buyer,itemOnMarket); + Market.SendMarketItemBoughtMessage(buyer, itemOnMarket); Message.Builder.SetCommand(Commands.MarketSellOrderUpdate) .WithData(new Dictionary { { k.sellOrder, marketSellOrder.ToDictionary() } }) @@ -535,7 +534,7 @@ public void FulfillBuyOrderInstantly(Character buyer, bool useBuyerCorporationWa item.Quantity = boughtQuantity; }); - Market.SendMarketItemBoughtMessage(buyer,itemOnMarket); + Market.SendMarketItemBoughtMessage(buyer, itemOnMarket); //average price _marketHandler.InsertAveragePrice(this, marketSellOrder.itemDefinition, boughtQuantity * marketSellOrder.price, boughtQuantity); @@ -553,7 +552,7 @@ public void FulfillBuyOrderInstantly(Character buyer, bool useBuyerCorporationWa item.Quantity = quantity; }); - Market.SendMarketItemBoughtMessage(buyer,itemOnMarket); + Market.SendMarketItemBoughtMessage(buyer, itemOnMarket); //average price _marketHandler.InsertAveragePrice(this, marketSellOrder.itemDefinition, quantity * marketSellOrder.price, quantity); @@ -637,14 +636,14 @@ public void BuyOrderFulfilledToCharacter(Character seller, bool useSellersCorpor } //pay out the fulfilled amount immediately using the price of the found buyorder to the seller - PayOutToSeller(seller,useSellersCorporationWallet,boughtItem.Definition,buyOrder.price,boughtItem.Quantity,TransactionType.marketSell,buyOrder.IsAffectsAverage(),forCorporation); + PayOutToSeller(seller, useSellersCorporationWallet, boughtItem.Definition, buyOrder.price, boughtItem.Quantity, TransactionType.marketSell, buyOrder.IsAffectsAverage(), forCorporation); - _centralBank.SubAmount(buyOrder.price*boughtItem.Quantity,TransactionType.marketSell); + _centralBank.SubAmount(buyOrder.price * boughtItem.Quantity, TransactionType.marketSell); - Market.SendMarketItemBoughtMessage(buyer,boughtItem); + Market.SendMarketItemBoughtMessage(buyer, boughtItem); Message.Builder.SetCommand(Commands.MarketBuyOrderUpdate) - .WithData(new Dictionary {{k.buyOrder, buyOrder.ToDictionary()}}) + .WithData(new Dictionary { { k.buyOrder, buyOrder.ToDictionary() } }) .ToCharacters(seller, buyer) .Send(); } @@ -665,19 +664,18 @@ public void FiniteVendorBuyOrderTakesTheItem(bool useSellerCorporationWallet, Ma } //do payout - PayOutToSeller(seller,useSellerCorporationWallet,boughtItem.Definition,vendorBuyOrder.price,boughtItem.Quantity,TransactionType.marketSell,true,false); + PayOutToSeller(seller, useSellerCorporationWallet, boughtItem.Definition, vendorBuyOrder.price, boughtItem.Quantity, TransactionType.marketSell, true, false); - _centralBank.SubAmount(vendorBuyOrder.price*boughtItem.Quantity,TransactionType.marketSell); + _centralBank.SubAmount(vendorBuyOrder.price * boughtItem.Quantity, TransactionType.marketSell); Message.Builder.SetCommand(Commands.MarketBuyOrderUpdate) - .WithData(new Dictionary {{k.buyOrder, vendorBuyOrder.ToDictionary()}}) + .WithData(new Dictionary { { k.buyOrder, vendorBuyOrder.ToDictionary() } }) .ToCharacter(seller) .Send(); } public void FulfillSellOrderInstantly(Character seller, bool useSellerCorporationWallet, MarketOrder buyOrder, Item itemToSell, Container container) { - if (!buyOrder.isVendorItem) { var buyer = Character.GetByEid(buyOrder.submitterEID); @@ -698,7 +696,7 @@ public void FulfillSellOrderInstantly(Character seller, bool useSellerCorporatio BuyOrderFulfilledToCharacter(seller, useSellerCorporationWallet, buyOrder, itemToSell.Quantity, container, itemToSell, buyer); Message.Builder.SetCommand(Commands.MarketItemSold) - .WithData(new Dictionary {{k.item, itemToSell.BaseInfoToDictionary()}}) + .WithData(new Dictionary { { k.item, itemToSell.BaseInfoToDictionary() } }) .ToCharacter(seller) .Send(); } @@ -706,6 +704,8 @@ public void FulfillSellOrderInstantly(Character seller, bool useSellerCorporatio return; } + int quantity = 0; + // a vendor wants to buy this item if (buyOrder.quantity > 0) { @@ -716,9 +716,10 @@ public void FulfillSellOrderInstantly(Character seller, bool useSellerCorporatio FiniteVendorBuyOrderTakesTheItem(useSellerCorporationWallet, buyOrder, itemToSell, seller); Message.Builder.SetCommand(Commands.MarketItemSold) - .WithData(new Dictionary {{k.item, itemToSell.BaseInfoToDictionary()}}) + .WithData(new Dictionary { { k.item, itemToSell.BaseInfoToDictionary() } }) .ToCharacter(seller) .Send(); + quantity = itemToSell.Quantity; } else if (buyOrder.quantity < itemToSell.Quantity) { @@ -726,21 +727,54 @@ public void FulfillSellOrderInstantly(Character seller, bool useSellerCorporatio itemToSell.Quantity = itemToSell.Quantity - buyOrder.quantity; //do payout - PayOutToSeller(seller,useSellerCorporationWallet,itemToSell.Definition,buyOrder.price,buyOrder.quantity,TransactionType.marketSell,true,false); + PayOutToSeller(seller, useSellerCorporationWallet, itemToSell.Definition, buyOrder.price, buyOrder.quantity, TransactionType.marketSell, true, false); //average price - _marketHandler.InsertAveragePrice(this, itemToSell.Definition, buyOrder.quantity*buyOrder.price, buyOrder.quantity); - - _centralBank.SubAmount(buyOrder.quantity*buyOrder.price,TransactionType.marketSell); - + _marketHandler.InsertAveragePrice(this, itemToSell.Definition, buyOrder.quantity * buyOrder.price, buyOrder.quantity); + + _centralBank.SubAmount(buyOrder.quantity * buyOrder.price, TransactionType.marketSell); + + // Log plasma sold and income earned + if (itemToSell.ED.CategoryFlags.IsCategory(CategoryFlags.cf_reactor_plasma)) + { + using (TransactionScope scope = Db.CreateTransaction()) + { + _ = Db.Query() + .CommandText("exec sp_RecordPlasmaSold @sold_on, @plasma_type, @quantity, @income") + .SetParameter("@sold_on", DateTime.UtcNow) + .SetParameter("@plasma_type", itemToSell.ED.Name) + .SetParameter("@quantity", quantity) + .SetParameter("@income", buyOrder.price * quantity) + .ExecuteNonQuery(); + scope.Complete(); + } + } + + quantity = buyOrder.quantity; buyOrder.quantity = 0; //signal to client Message.Builder.SetCommand(Commands.MarketBuyOrderUpdate) - .WithData(new Dictionary {{k.buyOrder, buyOrder.ToDictionary()}}) + .WithData(new Dictionary { { k.buyOrder, buyOrder.ToDictionary() } }) .ToCharacter(seller) .Send(); } + // Log plasma sold and income earned + if (itemToSell.ED.CategoryFlags.IsCategory(CategoryFlags.cf_reactor_plasma)) + { + using (TransactionScope scope = Db.CreateTransaction()) + { + _ = Db.Query() + .CommandText("exec sp_RecordPlasmaSold @sold_on, @plasma_type, @quantity, @income") + .SetParameter("@sold_on", DateTime.UtcNow) + .SetParameter("@plasma_type", itemToSell.ED.Name) + .SetParameter("@quantity", quantity) + .SetParameter("@income", buyOrder.price * quantity) + .ExecuteNonQuery(); + scope.Complete(); + } + } + return; } @@ -748,14 +782,30 @@ public void FulfillSellOrderInstantly(Character seller, bool useSellerCorporatio Repository.Delete(itemToSell); //do payout - PayOutToSeller(seller,useSellerCorporationWallet,itemToSell.Definition,buyOrder.price,itemToSell.Quantity,TransactionType.marketSell,true,false); + PayOutToSeller(seller, useSellerCorporationWallet, itemToSell.Definition, buyOrder.price, itemToSell.Quantity, TransactionType.marketSell, true, false); - _centralBank.SubAmount(buyOrder.price*itemToSell.Quantity,TransactionType.marketSell); + _centralBank.SubAmount(buyOrder.price * itemToSell.Quantity, TransactionType.marketSell); Message.Builder.SetCommand(Commands.MarketItemSold) - .WithData(new Dictionary {{k.item, itemToSell.BaseInfoToDictionary()}}) + .WithData(new Dictionary { { k.item, itemToSell.BaseInfoToDictionary() } }) .ToCharacter(seller) .Send(); + + // Log plasma sold and income earned + if (itemToSell.ED.CategoryFlags.IsCategory(CategoryFlags.cf_reactor_plasma)) + { + using (TransactionScope scope = Db.CreateTransaction()) + { + _ = Db.Query() + .CommandText("exec sp_RecordPlasmaSold @sold_on, @plasma_type, @quantity, @income") + .SetParameter("@sold_on", DateTime.UtcNow) + .SetParameter("@plasma_type", itemToSell.ED.Name) + .SetParameter("@quantity", itemToSell.Quantity) + .SetParameter("@income", buyOrder.price * itemToSell.Quantity) + .ExecuteNonQuery(); + scope.Complete(); + } + } } /// @@ -828,7 +878,7 @@ public void InsertVendorSellOrder(int definition, double price, long vendorEid = public void AddOtherStuffToGammaMarket() { //229 898 899 900 901 902 5844 5375 5134 5137 tile charges - InsertVendorSellOrder(229,90); + InsertVendorSellOrder(229, 90); InsertVendorSellOrder(898, 90); InsertVendorSellOrder(899, 90); InsertVendorSellOrder(900, 90); @@ -891,7 +941,7 @@ public void AddCategoryToMarket(long vendorEID, string categoryFlag, int duratio foreach (var ed in _entityServices.Defaults.GetAll().GetByCategoryFlags(cf)) { if (!ed.IsSellable) continue; - + if (!addNamed && ed.Name.Contains("named")) continue; @@ -899,12 +949,12 @@ public void AddCategoryToMarket(long vendorEID, string categoryFlag, int duratio { if (!ed.Name.Contains(nameFilter)) continue; } - + const string insertCmdText = @"insert marketitems (marketeid, itemdefinition, submittereid, duration, isSell, price, quantity, isvendoritem) values (@marketeid, @itemdefinition, @submittereid, @duration, @isSell, @price, @quantity, @isvendoritem)"; Db.Query().CommandText(insertCmdText) .SetParameter("@marketeid", Eid) - .SetParameter("@itemdefinition",ed.Definition) + .SetParameter("@itemdefinition", ed.Definition) .SetParameter("@submittereid", vendorEID) .SetParameter("@duration", duration) .SetParameter("@isSell", isSell) @@ -936,15 +986,15 @@ public static void AutoProcessSellorders(MarketOrder sellOrder, MarketOrder buyO if (sellOrder.itemEid == null) return; //wtf - var itemToSell = Item.GetOrThrow((long) sellOrder.itemEid); + var itemToSell = Item.GetOrThrow((long)sellOrder.itemEid); var buyer = Character.GetByEid(buyOrder.submitterEID); - + if (itemToSell.Quantity > buyOrder.quantity) { //az item tobb darabbol all, kistackolunk belole var boughtItem = itemToSell.Unstack(buyOrder.quantity); market.BuyOrderFulfilledToCharacter(seller, useSellerCorporationWallet, buyOrder, buyOrder.quantity, null, boughtItem, buyer); - + //elmentjuk, o marad fent a marketen itemToSell.Save(); @@ -965,10 +1015,10 @@ public static void AutoProcessSellorders(MarketOrder sellOrder, MarketOrder buyO } } - public static void SendMarketItemBoughtMessage(Character character,Item item) + public static void SendMarketItemBoughtMessage(Character character, Item item) { Message.Builder.SetCommand(Commands.MarketItemBought) - .WithData(new Dictionary { { k.item,item.BaseInfoToDictionary() } }) + .WithData(new Dictionary { { k.item, item.BaseInfoToDictionary() } }) .ToCharacter(character) .Send(); } @@ -983,7 +1033,7 @@ public double GetMarketTaxRate(Character character) return (TaxMultiplier + character.GetExtensionsBonusSummary(ExtensionNames.MARKET_TRANSACTION_TAX)).Clamp(); } - public static double GetRealMarketFee(Character character,int duration) + public static double GetRealMarketFee(Character character, int duration) { var realMarketFee = MARKET_FEE * GetMarketFeeRate(character) * duration; return realMarketFee; diff --git a/src/Perpetuum/Services/MarketEngine/MarketAutoOrdersManager.cs b/src/Perpetuum/Services/MarketEngine/MarketAutoOrdersManager.cs new file mode 100644 index 000000000..5fd4ddc73 --- /dev/null +++ b/src/Perpetuum/Services/MarketEngine/MarketAutoOrdersManager.cs @@ -0,0 +1,51 @@ +using Perpetuum.Data; +using Perpetuum.Threading.Process; +using Perpetuum.Timers; +using System; +using System.Transactions; + +namespace Perpetuum.Services.MarketEngine +{ + public class MarketAutoOrdersManager : IProcess + { + private readonly TimerList _timers = new TimerList(); + + public void Start() + { + RecalculatePricesAndRenewOrders(); + Init(); + } + + public void Stop() + { + } + + public void Update(TimeSpan time) + { + _timers.Update(time); + } + + private void Init() + { + _timers.Add(new TimerAction(RecalculatePricesAndRenewOrders, TimeSpan.FromDays(1))); + + // Debug purposes, do not uncomment + //_timers.Add(new TimerAction(RecalculatePricesAndRenewOrders, TimeSpan.FromMinutes(1))); + } + + private void RecalculatePricesAndRenewOrders() + { + using (TransactionScope scope = Db.CreateTransaction()) + { + _ = Db.Query() + .CommandText("exec recalculate_raw_material_prices") + .ExecuteNonQuery(); + _ = Db.Query() + .CommandText("exec usp_RefreshAutoMarketOrders") + .ExecuteNonQuery(); + + scope.Complete(); + } + } + } +} diff --git a/src/Perpetuum/Services/MarketEngine/MarketHandler.cs b/src/Perpetuum/Services/MarketEngine/MarketHandler.cs index cd4ddc778..2fe4c1bf5 100644 --- a/src/Perpetuum/Services/MarketEngine/MarketHandler.cs +++ b/src/Perpetuum/Services/MarketEngine/MarketHandler.cs @@ -1,14 +1,14 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.Caching; -using Perpetuum.Accounting.Characters; +using Perpetuum.Accounting.Characters; using Perpetuum.Data; using Perpetuum.EntityFramework; using Perpetuum.ExportedTypes; using Perpetuum.Log; using Perpetuum.Units.DockingBases; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Caching; namespace Perpetuum.Services.MarketEngine { @@ -20,12 +20,12 @@ namespace Perpetuum.Services.MarketEngine public class MarketHandler { private readonly DockingBaseHelper _dockingBaseHelper; - + /// /// marketEid -> MarketPriceCollector /// private readonly ConcurrentDictionary _marketPriceCollectors = new ConcurrentDictionary(); - private readonly ConcurrentDictionary _marketEidToDockingBaseEid = new ConcurrentDictionary(); + private readonly ConcurrentDictionary _marketEidToDockingBaseEid = new ConcurrentDictionary(); private readonly ObjectCache _visibleMarkets = new MemoryCache("visibleMarkets"); public MarketHandler(DockingBaseHelper dockingBaseHelper) @@ -70,7 +70,7 @@ public bool TryGetDockingBaseEidForMarketEid(long marketEid, out long baseEid) Logger.Exception(ex); return false; } - + //ok, load price collector for the market var pc = GetPriceCollectorByMarket(market); baseEid = pc.GetBaseEid(); @@ -109,11 +109,11 @@ public long GetTrainingMarketEid() Db.Query().CommandText(query) .SetParameter("@tb_def", EntityDefault.GetByName(DefinitionNames.TRAINING_DOCKING_BASE).Definition) .ExecuteScalar(); - + Logger.Info("training base market eid was found: " + tbm_eid); _trainingMarketEid = tbm_eid; - + } return _trainingMarketEid; @@ -144,7 +144,7 @@ private void HandleInsertAveragePrice(Market market, int itemDefinition, double { GetPriceCollectorByMarket(market).InsertAveragePrice(itemDefinition, price, qty); } - + private MarketAveragePriceEntry HandleGetAveragePriceByMarket(Market market, int definition) { var pc = GetPriceCollectorByMarket(market); @@ -170,9 +170,9 @@ private double HandleGetWorldAveragePriceByTrades(EntityDefault entityDefault) public Dictionary GetGlobalAverageHistory(int day, int itemDefinition) { - var startDate = DateTime.Today.AddDays(-1*day); + var startDate = DateTime.Today.AddDays(-1 * day); - var marketEidString = GetAllDefaultMarketsEids().ArrayToString(); + var marketEidString = GetAllDefaultMarketsEids().ArrayToString(); var count = 0; var prices = (from r in @@ -186,7 +186,7 @@ marketeid in (" + marketEidString + @") and " + .SetParameter("@day", day) .SetParameter("@startDate", startDate) .Execute() - select (object) new Dictionary + select (object)new Dictionary { {k.price, r.GetValue(0)}, {k.date, r.GetValue(1)},