Fixes dupe exception (#258)

- [X] Cleans up ActivatorUtil
- [X] Fixes dupe exception
- [X] Fixes a bug in BasePotion
- [X] Fixes a few possible memory leaks

Bumps release version
This commit is contained in:
Kamron Batman 2020-09-19 15:46:07 -07:00 • committed by GitHub
parent 4d6e584b6c
commit e9c1e4cbba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
66 changed files with 597 additions and 496 deletions

View file

@ -395,10 +395,11 @@ namespace Server.Engines.CannedEvil
{
try
{
prot.SendLocalizedMessage(1049368); // You have been rewarded for your dedication to Justice!
var scrollDupe = scroll.GetType().CreateEntityInstance<SpecialScroll>();
if (ActivatorUtil.CreateInstance(scroll.GetType()) is SpecialScroll scrollDupe)
if (scrollDupe != null)
{
prot.SendLocalizedMessage(1049368); // You have been rewarded for your dedication to Justice!
scrollDupe.Skill = scroll.Skill;
scrollDupe.Value = scroll.Value;
prot.AddToBackpack(scrollDupe);
@ -619,7 +620,7 @@ namespace Server.Engines.CannedEvil
try
{
Champion = ActivatorUtil.CreateInstance(ChampionSpawnInfo.GetInfo(m_Type).Champion) as Mobile;
Champion = ChampionSpawnInfo.GetInfo(m_Type).Champion.CreateInstance<Mobile>();
}
catch
{
@ -782,7 +783,7 @@ namespace Server.Engines.CannedEvil
{
try
{
return ActivatorUtil.CreateInstance(types.RandomElement()) as Mobile;
return types.RandomElement().CreateInstance<Mobile>();
}
catch
{

View file

@ -244,7 +244,7 @@ namespace Server.Engines.Craft
try
{
item = ActivatorUtil.CreateInstance(type) as Item;
item = type.CreateInstance<Item>();
}
catch
{
@ -1188,7 +1188,7 @@ namespace Server.Engines.Craft
}
else
{
item = ActivatorUtil.CreateInstance(ItemType) as Item;
item = ItemType.CreateInstance<Item>();
}
if (item != null)
@ -1428,27 +1428,22 @@ namespace Server.Engines.Craft
if (typeof(CustomCraft).IsAssignableFrom(m_CraftItem.ItemType))
{
CustomCraft cc = null;
try
{
cc = ActivatorUtil.CreateInstance(
m_CraftItem.ItemType,
m_CraftItem.ItemType.CreateInstance<CustomCraft>(
m_From,
m_CraftItem,
m_CraftSystem,
m_TypeRes,
m_Tool,
quality
) as CustomCraft;
)?.EndCraftAction();
}
catch
catch (Exception e)
{
// ignored
Console.WriteLine(e);
}
cc?.EndCraftAction();
return;
}

View file

@ -94,7 +94,7 @@ namespace Server.Engines.Craft
}
var resourceType = info.ResourceTypes[0];
var ingot = (Item)ActivatorUtil.CreateInstance(resourceType);
var ingot = resourceType.CreateInstance<Item>();
if (item is DragonBardingDeed || item is BaseArmor armor && armor.PlayerConstructed ||
item is BaseWeapon weapon && weapon.PlayerConstructed ||

View file

@ -37,7 +37,7 @@ namespace Server.Engines.Craft
public override int GumpTitleNumber => 1044009;
public static CraftSystem CraftSystem => m_CraftSystem ?? (m_CraftSystem = new DefInscription());
public static CraftSystem CraftSystem => m_CraftSystem ??= new DefInscription();
public override double GetChanceAtMin(CraftItem item) => 0.0;
@ -55,9 +55,9 @@ namespace Server.Engines.Craft
if (typeItem != null)
{
var o = ActivatorUtil.CreateInstance(typeItem);
var scroll = typeItem.CreateEntityInstance<SpellScroll>();
if (o is SpellScroll scroll)
if (scroll != null)
{
var hasSpell = Spellbook.Find(from, scroll.SpellID)?.HasSpell(scroll.SpellID) == true;
@ -65,11 +65,6 @@ namespace Server.Engines.Craft
return hasSpell ? 0 : 1042404; // null : You don't have that spell!
}
if (o is Item item)
{
item.Delete();
}
}
return 0;

View file

@ -340,16 +340,11 @@ namespace Server.Engines.Doom
return;
}
var obj = ActivatorUtil.CreateInstance(type);
var mob = type.CreateEntityInstance<Mobile>();
if (obj is Item item)
{
item.Delete();
}
else if (obj is Mobile mob)
if (mob != null)
{
mob.MoveToWorld(GetWorldLocation(), Map);
Creatures.Add(mob);
}
}

View file

@ -19,7 +19,7 @@ namespace Server.Factions
{
try
{
return ActivatorUtil.CreateInstance(Definition.Type) as BaseFactionGuard;
return Definition.Type.CreateInstance<BaseFactionGuard>();
}
catch
{

View file

@ -41,7 +41,7 @@ namespace Server.Factions
{
try
{
return ActivatorUtil.CreateInstance(type);
return type.CreateInstance<object>();
}
catch
{

View file

@ -19,7 +19,7 @@ namespace Server.Factions
{
try
{
return ActivatorUtil.CreateInstance(Definition.Type, town, faction) as BaseFactionVendor;
return Definition.Type.CreateInstance<BaseFactionVendor>(town, faction);
}
catch
{

View file

@ -55,7 +55,7 @@ namespace Server
{
if (weight < item.Weight)
{
var obj = item.Construct();
var obj = item.Type.CreateInstance<Item>();
if (obj != null)
{
@ -188,8 +188,6 @@ namespace Server
public int Weight { get; }
public Type Type { get; }
public Item Construct() => ActivatorUtil.CreateInstance(Type) as Item;
}
}
}

View file

@ -51,7 +51,7 @@ namespace Server.Factions
{
try
{
return ActivatorUtil.CreateInstance(TrapType, m_Faction, from) as BaseFactionTrap;
return TrapType.CreateInstance<BaseFactionTrap>(m_Faction, from);
}
catch
{

View file

@ -91,7 +91,7 @@ namespace Server.Factions
if (entry.Chance > Utility.Random(100))
{
releaseTime = DateTime.UtcNow + entry.Hold;
return (Spell)ActivatorUtil.CreateInstance(entry.Spell, mob, null);
return entry.Spell.CreateInstance<Spell>(mob, null);
}
}
@ -406,9 +406,9 @@ namespace Server.Factions
{
if (m_Mobile.Target != null)
m_Mobile.Target.Cancel( m_Mobile, TargetCancelType.Canceled );
new TeleportSpell( m_Mobile, null ).Cast();
m_Mobile.DebugSay( "I am stuck, I'm going to try teleporting away" );
}
else*/
@ -744,7 +744,7 @@ namespace Server.Factions
}
else if (types.Count == 1)
{
spell = ActivatorUtil.CreateInstance(types[0], m_Guard, null) as Spell;
spell = types[0].CreateInstance<Spell>(m_Guard, null);
}
}
else if (types.Count > 0)
@ -796,7 +796,7 @@ namespace Server.Factions
}
else if (types.Count == 1)
{
spell = (Spell)ActivatorUtil.CreateInstance(types[0], m_Guard, null);
spell = types[0].CreateInstance<Spell>(m_Guard, null);
}
}
}
@ -804,24 +804,14 @@ namespace Server.Factions
if (spell != null && m_Guard.HitsMax - m_Guard.Hits + 10 > Utility.Random(100))
{
Type type = null;
if (spell is GreaterHealSpell)
Type type = spell switch
{
type = typeof(BaseHealPotion);
}
else if (spell is CureSpell)
{
type = typeof(BaseCurePotion);
}
else if (spell is StrengthSpell)
{
type = typeof(BaseStrengthPotion);
}
else if (spell is AgilitySpell)
{
type = typeof(BaseAgilityPotion);
}
GreaterHealSpell _ => typeof(BaseHealPotion),
CureSpell _ => typeof(BaseCurePotion),
StrengthSpell _ => typeof(BaseStrengthPotion),
AgilitySpell _ => typeof(BaseAgilityPotion),
_ => null
};
if (type == typeof(BaseHealPotion) && !m_Guard.CanBeginAction(type))
{

View file

@ -268,7 +268,7 @@ namespace Server.Engines.Harvest
{
try
{
return ActivatorUtil.CreateInstance(type) as Item;
return type.CreateInstance<Item>();
}
catch
{

View file

@ -387,16 +387,17 @@ namespace Server.Engines.Harvest
if (res == resource && res.Types.Length >= 3)
{
var map = from.Map;
if (map == null)
{
return;
}
try
{
var map = from.Map;
if (map == null)
{
return;
}
if (ActivatorUtil.CreateInstance(res.Types[2], 25) is BaseCreature spawned)
var spawned = res.Types[2].CreateEntityInstance<BaseCreature>(25);
if (spawned != null)
{
var offset = Utility.Random(8) * 2;

View file

@ -69,7 +69,7 @@ namespace Server.Engines.MLQuests
try
{
quest = ActivatorUtil.CreateInstance(type) as MLQuest;
quest = type.CreateInstance<MLQuest>();
}
catch
{

View file

@ -49,17 +49,17 @@ namespace Server.Engines.MLQuests.Objectives
for (var i = 0; i < Amount; ++i)
{
if (!(ActivatorUtil.CreateInstance(Delivery) is Item item))
{
continue;
}
var item = Delivery.CreateEntityInstance<Item>();
delivery.Add(item);
if (item.Stackable && Amount > 1)
if (item != null)
{
item.Amount = Amount;
break;
delivery.Add(item);
if (item.Stackable && Amount > 1)
{
item.Amount = Amount;
break;
}
}
}

View file

@ -54,7 +54,7 @@ namespace Server.Engines.MLQuests.Rewards
try
{
spawnedItem = ActivatorUtil.CreateInstance(m_Type) as Item;
spawnedItem = m_Type.CreateInstance<Item>();
}
catch (Exception e)
{

View file

@ -310,18 +310,12 @@ namespace Server.Items
foreach (var taep in m_Table)
{
var contains = false;
for (var i = 0; !contains && i < taep.Tiles.Length; i += 2)
for (var i = 0; i < taep.Tiles.Length; i += 2)
{
contains = tileID >= taep.Tiles[i] && tileID <= taep.Tiles[i + 1];
}
if (contains)
{
var effect =
(GreenThornsEffect)ActivatorUtil.CreateInstance(taep.Effect, land.Location, from.Map, from);
return effect;
if (tileID >= taep.Tiles[i] && tileID <= taep.Tiles[i + 1])
{
return taep.Effect.CreateInstance<GreenThornsEffect>(land.Location, from.Map, from);
}
}
}

View file

@ -45,6 +45,6 @@ namespace Server.Engines.Plants
return null;
}
public Item CreateResource() => (Item)ActivatorUtil.CreateInstance(ResourceType);
public Item CreateResource() => ResourceType.CreateInstance<Item>();
}
}

View file

@ -3,13 +3,13 @@ using Server.Utilities;
namespace Server.Engines.Quests
{
public class QuestSerializer
public static class QuestSerializer
{
public static object Construct(Type type)
{
try
{
return ActivatorUtil.CreateInstance(type);
return type.CreateInstance<object>();
}
catch
{

View file

@ -563,153 +563,162 @@ namespace Server.Engines.Spawners
var type = AssemblyHandler.FindFirstTypeForName(entry.SpawnedName);
if (type != null)
if (type == null)
{
try
flags = EntryFlags.InvalidType;
return false;
}
try
{
IEntity entity = null;
string[] paramargs;
string[] propargs;
propargs = string.IsNullOrEmpty(entry.Properties)
? Array.Empty<string>()
: CommandSystem.Split(entry.Properties.Trim());
var props = FormatProperties(propargs);
var realProps = GetTypeProperties(type, props);
if (realProps == null)
{
object o = null;
string[] paramargs;
string[] propargs;
flags = EntryFlags.InvalidProps;
return false;
}
propargs = string.IsNullOrEmpty(entry.Properties)
? Array.Empty<string>()
: CommandSystem.Split(entry.Properties.Trim());
paramargs = string.IsNullOrEmpty(entry.Parameters)
? Array.Empty<string>()
: entry.Parameters.Trim().Split(' ');
var props = FormatProperties(propargs);
if (paramargs.Length == 0)
{
entity = type.CreateInstance<IEntity>(
ci => Add.IsConstructible(ci, AccessLevel.Developer)
);
}
else
{
var ctors = type.GetConstructors();
var realProps = GetTypeProperties(type, props);
if (realProps == null)
for (var i = 0; i < ctors.Length; ++i)
{
flags = EntryFlags.InvalidProps;
return false;
}
var ctor = ctors[i];
paramargs = string.IsNullOrEmpty(entry.Parameters)
? Array.Empty<string>()
: entry.Parameters.Trim().Split(' ');
if (paramargs.Length == 0)
{
o = ActivatorUtil.CreateInstance(type, ci => Add.IsConstructible(ci, AccessLevel.Developer));
}
else
{
var ctors = type.GetConstructors();
for (var i = 0; i < ctors.Length; ++i)
if (Add.IsConstructible(ctor, AccessLevel.Developer))
{
var ctor = ctors[i];
var paramList = ctor.GetParameters();
if (Add.IsConstructible(ctor, AccessLevel.Developer))
if (paramargs.Length == paramList.Length)
{
var paramList = ctor.GetParameters();
var paramValues = Add.ParseValues(paramList, paramargs);
if (paramargs.Length == paramList.Length)
if (paramValues != null)
{
var paramValues = Add.ParseValues(paramList, paramargs);
if (paramValues != null)
{
o = ctor.Invoke(paramValues);
break;
}
entity = ctor.Invoke(paramValues) as IEntity;
break;
}
}
}
}
for (var i = 0; i < realProps.Length; i++)
{
if (realProps[i] != null)
{
object toSet = null;
var result = Properties.ConstructFromString(
realProps[i].PropertyType,
o,
props[i, 1],
ref toSet
);
if (result == null)
{
realProps[i].SetValue(o, toSet, null);
}
else
{
flags = EntryFlags.InvalidProps;
(o as ISpawnable)?.Delete();
return false;
}
}
}
if (o is Mobile m)
{
Spawned.Add(m, entry);
entry.Spawned.Add(m);
var loc = m is BaseVendor ? Location : GetSpawnPosition(m, map);
m.OnBeforeSpawn(loc, map);
InvalidateProperties();
m.MoveToWorld(loc, map);
if (m is BaseCreature c)
{
var walkrange = GetWalkingRange();
c.RangeHome = walkrange >= 0 ? walkrange : m_HomeRange;
c.CurrentWayPoint = WayPoint;
if (m_Team > 0)
{
c.Team = m_Team;
}
c.Home = Location;
c.HomeMap = Map;
}
m.Spawner = this;
m.OnAfterSpawn();
}
else if (o is Item item)
{
Spawned.Add(item, entry);
entry.Spawned.Add(item);
var loc = GetSpawnPosition(item, map);
item.OnBeforeSpawn(loc, map);
item.MoveToWorld(loc, map);
item.Spawner = this;
item.OnAfterSpawn();
}
else
{
flags = EntryFlags.InvalidType | EntryFlags.InvalidParams;
return false;
}
}
catch (Exception e)
if (entity == null)
{
Console.WriteLine($"EXCEPTION CAUGHT: {Serial}");
Console.WriteLine(e);
flags = EntryFlags.InvalidType | EntryFlags.InvalidParams;
return false;
}
InvalidateProperties();
return true;
for (var i = 0; i < realProps.Length; i++)
{
if (realProps[i] != null)
{
object toSet = null;
var result = Properties.ConstructFromString(
realProps[i].PropertyType,
entity,
props[i, 1],
ref toSet
);
if (result == null)
{
realProps[i].SetValue(entity, toSet, null);
}
else
{
flags = EntryFlags.InvalidProps;
(entity as ISpawnable)?.Delete();
return false;
}
}
}
if (entity is Mobile m)
{
Spawned.Add(m, entry);
entry.Spawned.Add(m);
var loc = m is BaseVendor ? Location : GetSpawnPosition(m, map);
m.OnBeforeSpawn(loc, map);
InvalidateProperties();
m.MoveToWorld(loc, map);
if (m is BaseCreature c)
{
var walkrange = GetWalkingRange();
c.RangeHome = walkrange >= 0 ? walkrange : m_HomeRange;
c.CurrentWayPoint = WayPoint;
if (m_Team > 0)
{
c.Team = m_Team;
}
c.Home = Location;
c.HomeMap = Map;
}
m.Spawner = this;
m.OnAfterSpawn();
}
else if (entity is Item item)
{
Spawned.Add(item, entry);
entry.Spawned.Add(item);
var loc = GetSpawnPosition(item, map);
item.OnBeforeSpawn(loc, map);
item.MoveToWorld(loc, map);
item.Spawner = this;
item.OnAfterSpawn();
}
else
{
// Other IEntity types that might get created are simply not supported
flags = EntryFlags.InvalidType | EntryFlags.InvalidParams;
return false;
}
}
catch (Exception e)
{
Console.WriteLine($"EXCEPTION CAUGHT: {Serial}");
Console.WriteLine(e);
return false;
}
flags = EntryFlags.InvalidType;
return false;
InvalidateProperties();
return true;
}
public virtual int GetWalkingRange() => m_WalkingRange;

View file

@ -96,7 +96,7 @@ namespace Server.Engines.Spawners
try
{
var spawner = ActivatorUtil.CreateInstance(type, json, options) as ISpawner;
var spawner = type.CreateInstance<ISpawner>(json, options);
spawner!.MoveToWorld(location, map);
spawner!.Respawn();

View file

@ -157,47 +157,40 @@ namespace Server.Misc
var chance = A * Math.Pow(10, B * x);
if (chance > Utility.RandomDouble())
if (chance <= Utility.RandomDouble())
{
Item i = null;
return;
}
try
Item i;
try
{
i = m_LesserArtifacts[(int)DropEra - 1].RandomElement().CreateInstance<Item>();
}
catch
{
return;
}
// For your valor in combating the fallen beast, a special artifact has been bestowed on you.
pm.SendLocalizedMessage(1062317);
if (!pm.PlaceInBackpack(i))
{
if (pm.BankBox?.TryDropItem(killer, i, false) == true)
{
i = ActivatorUtil.CreateInstance(
m_LesserArtifacts[(int)DropEra - 1].RandomElement()
)
as
Item;
pm.SendLocalizedMessage(1079730); // The item has been placed into your bank box.
}
catch
else
{
// ignored
}
if (i != null)
{
pm.SendLocalizedMessage(
1062317
); // For your valor in combating the fallen beast, a special artifact has been bestowed on you.
if (!pm.PlaceInBackpack(i))
{
if (pm.BankBox?.TryDropItem(killer, i, false) == true)
{
pm.SendLocalizedMessage(1079730); // The item has been placed into your bank box.
}
else
{
pm.SendLocalizedMessage(
1072523
); // You find an artifact, but your backpack and bank are too full to hold it.
i.MoveToWorld(pm.Location, pm.Map);
}
}
pm.ToTTotalMonsterFame = 0;
// You find an artifact, but your backpack and bank are too full to hold it.
pm.SendLocalizedMessage(1072523);
i.MoveToWorld(pm.Location, pm.Map);
}
}
pm.ToTTotalMonsterFame = 0;
}
}
}
@ -594,7 +587,7 @@ namespace Server.Gumps
try
{
item = (Item)ActivatorUtil.CreateInstance(t.Type);
item = t.Type.CreateInstance<Item>();
}
catch
{

View file

@ -69,7 +69,7 @@ namespace Server.Engines.VeteranRewards
{
try
{
var item = ActivatorUtil.CreateInstance(ItemType, Args) as Item;
var item = ItemType.CreateInstance<Item>(Args);
if (item is IRewardItem rewardItem)
{