Merge remote-tracking branch 'upstream/dev' into fixes
This commit is contained in:
commit
c3668122d7
31 changed files with 373 additions and 274 deletions
|
|
@ -22,7 +22,7 @@ Some of these parameters can be set automatically by using [Bifrost](https://git
|
|||
|
||||
These require further checking for compatibility with various versions of the client.
|
||||
|
||||
### ClientApp::Initialize
|
||||
### ClientApp::Initialize()
|
||||
|
||||
| Parameter | Description | Values |
|
||||
| ----------------------- | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
|
||||
|
|
@ -42,7 +42,7 @@ These require further checking for compatibility with various versions of the cl
|
|||
| -novalidate | | |
|
||||
| -nohardwareinfo | | |
|
||||
|
||||
### ClientAppSettingsPostCoreInit::Initialize
|
||||
### ClientAppSettingsPostCoreInit::Initialize()
|
||||
|
||||
| Parameter | Description | Values |
|
||||
| ---------------------- | -------------------------------------------------------------------------------------------- | ------------ |
|
||||
|
|
@ -86,7 +86,7 @@ These require further checking for compatibility with various versions of the cl
|
|||
| -streaming | | |
|
||||
| -platform= | | orbis, dingo |
|
||||
|
||||
### SiteConfig::ParseCommandLine
|
||||
### SiteConfig::ParseCommandLine()
|
||||
|
||||
| Parameter | Description | Values |
|
||||
| ------------ | ----------- | ------ |
|
||||
|
|
@ -94,44 +94,50 @@ These require further checking for compatibility with various versions of the cl
|
|||
| -authserver= | | |
|
||||
| -authurl= | | |
|
||||
|
||||
### ClientGame::Initialize
|
||||
### ClientGame::Initialize()
|
||||
|
||||
| Parameter | Description | Values |
|
||||
| ----------- | ----------- | ------ |
|
||||
| -nooverwolf | | |
|
||||
|
||||
### Atlas::Initialize
|
||||
### Atlas::Initialize()
|
||||
|
||||
| Parameter | Description | Values |
|
||||
| ------------- | ----------- | ------ |
|
||||
| -nomapmarkers | | |
|
||||
|
||||
### AudioManager::Initialize
|
||||
### AudioManager::Initialize()
|
||||
|
||||
| Parameter | Description | Values |
|
||||
| -------------- | ----------- | ------ |
|
||||
| -nomusic | | |
|
||||
| -foleyineditor | | |
|
||||
|
||||
### UnrealAudioManager::Initialize
|
||||
### UnrealAudioManager::Initialize()
|
||||
|
||||
| Parameter | Description | Values |
|
||||
| ------------------ | ----------- | ------ |
|
||||
| -audioglobalfocus | | |
|
||||
| -audiofilepackages | | |
|
||||
|
||||
### UnrealGameAdapter::Initialize
|
||||
### UnrealGameAdapter::Initialize()
|
||||
|
||||
| Parameter | Description | Values |
|
||||
| ---------------- | ----------- | ------ |
|
||||
| -dependencygraph | | |
|
||||
|
||||
### UnrealGameAdapter::SendSteamUserInfo
|
||||
### UnrealGameAdapter::SendSteamUserInfo()
|
||||
|
||||
| Parameter | Description | Values |
|
||||
| ----------------------- | ----------- | ------ |
|
||||
| -steamachievementupdate | | |
|
||||
|
||||
### InitGazillionSystems()
|
||||
|
||||
| Parameter | Description | Values |
|
||||
| --------- | ------------------------ | ------------------------------------------------------------------------------ |
|
||||
| -locale= | Overrides client locale. | Name of locale file under `Data\Game\Loco` without extension (e.g. `eng.all`). |
|
||||
|
||||
## Logging Channels
|
||||
|
||||
You can specify channels for verbose logging using the following syntax: `-LoggingChannels=-ALL,+GAME`. Available channels:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Server Commands
|
||||
|
||||
This list was automatically generated on `2026.01.21 10:37:50 UTC` using server version `0.8.1`.
|
||||
This list was automatically generated on `2026.03.09 15:06:03 UTC` using server version `1.0.0`.
|
||||
|
||||
To see an up to date list of all commands, type !commands in the server console or the in-game chat. When invoking a command from in-game your account has to meet the user level requirement for the command.
|
||||
|
||||
|
|
@ -108,7 +108,7 @@ Commands for managing items.
|
|||
| Command | Description | User Level | Invoker Type |
|
||||
| ---------------------------- | -------------------------------------------------------------------------- | ---------- | ------------ |
|
||||
| !item cleardeliverybox | Destroys all items contained in the delivery box inventory. | Any | Client |
|
||||
| !item creditchest | Converts 500k credits to a sellable chest item. | Any | Client |
|
||||
| !item creditchest | Converts credits to a sellable chest item. | Any | Client |
|
||||
| !item destroyindestructible | Destroys indestructible items contained in the player's general inventory. | Any | Client |
|
||||
| !item drop [pattern] [count] | Creates and drops the specified item from the current avatar. | Admin | Client |
|
||||
| !item give [pattern] [count] | Creates and gives the specified item to the current player. | Admin | Client |
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<AssemblyVersion>0.8.1.0</AssemblyVersion>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
<FileVersion>$(AssemblyVersion)</FileVersion>
|
||||
<InformationalVersion>$(AssemblyVersion)</InformationalVersion>
|
||||
</PropertyGroup>
|
||||
|
|
|
|||
|
|
@ -19,23 +19,30 @@ namespace MHServerEmu.Core.Serialization
|
|||
Disk = 4 // Server <-> File
|
||||
}
|
||||
|
||||
// We are most likely not going to have as much versioning as the original game,
|
||||
// so we will use ArchiveVersion for all archive versioning. At some point when
|
||||
// things get more stable we may want to clear this and force a wipe of everything.
|
||||
public enum ArchiveVersion : uint
|
||||
{
|
||||
Invalid = 0,
|
||||
Initial = 1,
|
||||
AddedMissions = 2,
|
||||
AddedVendorPurchaseData = 3,
|
||||
ImplementedConditionPersistence = 4,
|
||||
ImplementedLoginRewards = 5,
|
||||
ImplementedMapDiscoveryDataPersistence = 6,
|
||||
AddedRegionProtoRefToMapDiscoveryData = 7,
|
||||
AddedUltimatePrestigeLevel = 8,
|
||||
// Versions 1-8 were used in the 0.x branch, so we start at 9 here.
|
||||
Initial = 9,
|
||||
|
||||
// Update the current version if you add any <---------
|
||||
Current = AddedUltimatePrestigeLevel
|
||||
Current = Initial
|
||||
}
|
||||
|
||||
public enum GameBuildNumber : uint
|
||||
{
|
||||
Invalid = 0,
|
||||
|
||||
// Changelist is the most consistent single number we have to identify different builds of the game, so use it for persistent archives.
|
||||
// Add more changelist numbers here for any other versions of the game we are going to support.
|
||||
_1_10_0_69 = 324,
|
||||
_1_10_0_643 = 16688,
|
||||
_1_48_0_1618 = 380454,
|
||||
_1_48_0_1712 = 391562,
|
||||
_1_52_0_1700 = 479899,
|
||||
_1_53_0_203 = 493640,
|
||||
|
||||
Current = _1_52_0_1700
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -53,7 +60,7 @@ namespace MHServerEmu.Core.Serialization
|
|||
[ThreadStatic]
|
||||
private static MemoryStream SharedAutoBuffer;
|
||||
|
||||
private readonly MemoryStream _bufferStream; // MemoryStream replaces AutoBuffer from the original implementation
|
||||
private readonly MemoryStream _buffer; // MemoryStream replaces StreamAutoBuffer from the original implementation
|
||||
|
||||
// C# coded stream implementation is buffered, so we have to use the same stream for the whole archive
|
||||
private readonly CodedOutputStream _cos;
|
||||
|
|
@ -114,12 +121,12 @@ namespace MHServerEmu.Core.Serialization
|
|||
InitializeBuffers();
|
||||
|
||||
// Reuse the same stream for all packing archives
|
||||
_bufferStream = SharedAutoBuffer;
|
||||
if (_bufferStream.Length > 0)
|
||||
_bufferStream.SetLength(0);
|
||||
_buffer = SharedAutoBuffer;
|
||||
if (_buffer.Length > 0)
|
||||
_buffer.SetLength(0);
|
||||
|
||||
// Use reflection hackery to reuse the same buffer for all coded output streams, see ProtobufHelper for details.
|
||||
_cos = ProtobufHelper.CodedOutputStreamEx.CreateInstance(_bufferStream, WriteBuffer);
|
||||
_cos = ProtobufHelper.CodedOutputStreamEx.CreateInstance(_buffer, WriteBuffer);
|
||||
|
||||
SerializeType = serializeType;
|
||||
ReplicationPolicy = replicationPolicy;
|
||||
|
|
@ -139,8 +146,8 @@ namespace MHServerEmu.Core.Serialization
|
|||
|
||||
InitializeBuffers();
|
||||
|
||||
_bufferStream = new(buffer);
|
||||
_cis = CodedInputStream.CreateInstance(_bufferStream, ReadBuffer);
|
||||
_buffer = new(buffer);
|
||||
_cis = CodedInputStream.CreateInstance(_buffer, ReadBuffer);
|
||||
|
||||
SerializeType = serializeType;
|
||||
IsPacking = false;
|
||||
|
|
@ -172,7 +179,7 @@ namespace MHServerEmu.Core.Serialization
|
|||
|
||||
public void Dispose()
|
||||
{
|
||||
_bufferStream.SetLength(0);
|
||||
_buffer.SetLength(0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -183,7 +190,7 @@ namespace MHServerEmu.Core.Serialization
|
|||
/// </remarks>
|
||||
public MemoryStream AccessAutoBuffer()
|
||||
{
|
||||
return _bufferStream;
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -192,12 +199,12 @@ namespace MHServerEmu.Core.Serialization
|
|||
public ByteString ToByteString()
|
||||
{
|
||||
// We use ByteString.Unsafe here to avoid copying data one extra time (Stream -> ByteString instead of Stream -> Buffer -> ByteString).
|
||||
return ByteString.Unsafe.FromBytes(_bufferStream.ToArray());
|
||||
return ByteString.Unsafe.FromBytes(_buffer.ToArray());
|
||||
}
|
||||
|
||||
public Span<byte> AsSpan()
|
||||
{
|
||||
byte[] buffer = _bufferStream.GetBuffer();
|
||||
byte[] buffer = _buffer.GetBuffer();
|
||||
return buffer.AsSpan(0, (int)CurrentOffset);
|
||||
}
|
||||
|
||||
|
|
@ -210,8 +217,14 @@ namespace MHServerEmu.Core.Serialization
|
|||
|
||||
if (IsPersistent)
|
||||
{
|
||||
// Write archive size placeholder that will be updated via UpdateSizeInArchive() when other data is written.
|
||||
WriteUnencodedStream(0u);
|
||||
|
||||
uint version = (uint)Version;
|
||||
success &= Transfer(ref version);
|
||||
|
||||
uint gameBuildNumber = (uint)GameBuildNumber.Current;
|
||||
success &= Transfer(ref gameBuildNumber);
|
||||
}
|
||||
else if (IsReplication)
|
||||
{
|
||||
|
|
@ -231,9 +244,24 @@ namespace MHServerEmu.Core.Serialization
|
|||
|
||||
if (IsPersistent)
|
||||
{
|
||||
uint sizeUsed = 0;
|
||||
success &= ReadUnencodedStream(ref sizeUsed);
|
||||
|
||||
if (sizeUsed != _buffer.Length)
|
||||
{
|
||||
SetError("Buffer size mismatch!");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint version = 0;
|
||||
success &= Transfer(ref version);
|
||||
Version = (ArchiveVersion)version;
|
||||
|
||||
// For now just log a warning if there is a game build mismatch, in the future we can use this for migration between versions.
|
||||
uint gameBuildNumber = 0;
|
||||
success &= Transfer(ref gameBuildNumber);
|
||||
if (gameBuildNumber != (uint)GameBuildNumber.Current)
|
||||
Logger.Warn($"Game build number mismatch: expected {(uint)GameBuildNumber.Current}, got {gameBuildNumber}");
|
||||
}
|
||||
else if (IsReplication)
|
||||
{
|
||||
|
|
@ -280,7 +308,7 @@ namespace MHServerEmu.Core.Serialization
|
|||
}
|
||||
else
|
||||
{
|
||||
_bufferStream.WriteByteAt(_lastBitEncodedOffset, bitBuffer);
|
||||
_buffer.WriteByteAt(_lastBitEncodedOffset, bitBuffer);
|
||||
if (numEncodedBits >= 5)
|
||||
_lastBitEncodedOffset = 0;
|
||||
}
|
||||
|
|
@ -633,7 +661,8 @@ namespace MHServerEmu.Core.Serialization
|
|||
|
||||
if (IsPacking)
|
||||
{
|
||||
return WriteVarint(ioData);
|
||||
WriteVarint(ioData);
|
||||
UpdateSizeInArchive();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -660,7 +689,8 @@ namespace MHServerEmu.Core.Serialization
|
|||
|
||||
if (IsPacking)
|
||||
{
|
||||
return WriteVarint(ioData);
|
||||
WriteVarint(ioData);
|
||||
UpdateSizeInArchive();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -702,7 +732,7 @@ namespace MHServerEmu.Core.Serialization
|
|||
/// </summary>
|
||||
private bool StartSizeChecking(ref long startPosition, ref uint size)
|
||||
{
|
||||
if (IsPersistent == false || Version < ArchiveVersion.AddedMissions)
|
||||
if (IsPersistent == false)
|
||||
return true;
|
||||
|
||||
// NOTE: COS/CIS are buffered, so we need to use their position, and not the one from the underlying stream.
|
||||
|
|
@ -728,7 +758,7 @@ namespace MHServerEmu.Core.Serialization
|
|||
/// </summary>
|
||||
private bool EndSizeChecking(ref long startPosition, ref uint size, bool skip)
|
||||
{
|
||||
if (IsPersistent == false || Version < ArchiveVersion.AddedMissions)
|
||||
if (IsPersistent == false)
|
||||
return true;
|
||||
|
||||
if (IsPacking)
|
||||
|
|
@ -756,6 +786,40 @@ namespace MHServerEmu.Core.Serialization
|
|||
return true;
|
||||
}
|
||||
|
||||
private bool UpdateSizeInArchive()
|
||||
{
|
||||
if (IsPersistent == false)
|
||||
return false;
|
||||
|
||||
if (IsPacking == false)
|
||||
{
|
||||
SetError("Cant use on unpack!");
|
||||
return false;
|
||||
}
|
||||
|
||||
Span<uint> sizeToken = GetSizeTokenAtOffset(0);
|
||||
if (sizeToken.Length == 0)
|
||||
{
|
||||
SetError("Error accessing size in the buffer!");
|
||||
return false;
|
||||
}
|
||||
|
||||
sizeToken[0] = (uint)CurrentOffset;
|
||||
return true;
|
||||
}
|
||||
|
||||
private Span<uint> GetSizeTokenAtOffset(uint offset)
|
||||
{
|
||||
if (CurrentOffset < offset + sizeof(uint))
|
||||
{
|
||||
SetError("Failed writing size in use!");
|
||||
return default;
|
||||
}
|
||||
|
||||
Span<byte> sizeToken = new(_buffer.GetBuffer(), (int)offset, sizeof(uint));
|
||||
return MemoryMarshal.Cast<byte, uint>(sizeToken);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Stream IO
|
||||
|
|
@ -767,6 +831,9 @@ namespace MHServerEmu.Core.Serialization
|
|||
{
|
||||
_cos.WriteRawByte(value);
|
||||
_cos.Flush();
|
||||
|
||||
UpdateSizeInArchive();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -797,6 +864,9 @@ namespace MHServerEmu.Core.Serialization
|
|||
_cos.WriteRawByte(@byte);
|
||||
|
||||
_cos.Flush();
|
||||
|
||||
UpdateSizeInArchive();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -833,7 +903,7 @@ namespace MHServerEmu.Core.Serialization
|
|||
// NOTE: PropertyCollection::serializeWithDefault() manipulates the archive buffer directly. First it allocates 4 bytes
|
||||
// for the number of properties, than it writes all the properties, and then it goes back and updates the number.
|
||||
// NOTE2: Persistent archives also do this for all ISerialize objects, except it writes the number of bytes written.
|
||||
return _bufferStream.WriteUInt32At(position, value);
|
||||
return _buffer.WriteUInt32At(position, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -948,7 +1018,7 @@ namespace MHServerEmu.Core.Serialization
|
|||
{
|
||||
if (_lastBitEncodedOffset == 0) return null;
|
||||
|
||||
if (_bufferStream.ReadByteAt(_lastBitEncodedOffset, out byte lastBitEncoded) == false)
|
||||
if (_buffer.ReadByteAt(_lastBitEncodedOffset, out byte lastBitEncoded) == false)
|
||||
{
|
||||
SetError("Failed getting last bit encoded!");
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<AssemblyVersion>0.8.1.0</AssemblyVersion>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
<FileVersion>$(AssemblyVersion)</FileVersion>
|
||||
<InformationalVersion>$(AssemblyVersion)</InformationalVersion>
|
||||
</PropertyGroup>
|
||||
|
|
@ -21,6 +21,7 @@
|
|||
<None Remove="SQLite\Scripts\Migrations\2.sql" />
|
||||
<None Remove="SQLite\Scripts\Migrations\3.sql" />
|
||||
<None Remove="SQLite\Scripts\Migrations\4.sql" />
|
||||
<None Remove="SQLite\Scripts\Migrations\5.sql" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
@ -31,6 +32,7 @@
|
|||
<EmbeddedResource Include="SQLite\Scripts\Migrations\2.sql" />
|
||||
<EmbeddedResource Include="SQLite\Scripts\Migrations\3.sql" />
|
||||
<EmbeddedResource Include="SQLite\Scripts\Migrations\4.sql" />
|
||||
<EmbeddedResource Include="SQLite\Scripts\Migrations\5.sql" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -16,12 +16,12 @@ namespace MHServerEmu.DatabaseAccess.Models
|
|||
[Flags]
|
||||
public enum AccountFlags
|
||||
{
|
||||
None = 0,
|
||||
IsBanned = 1 << 0,
|
||||
IsArchived = 1 << 1,
|
||||
IsPasswordExpired = 1 << 2,
|
||||
DEPRECATEDLinuxCompatibilityMode = 1 << 3, // This flag used to disable session token verification, but it is no longer needed for Linux users
|
||||
IsWhitelisted = 1 << 4,
|
||||
None = 0,
|
||||
IsBanned = 1 << 0,
|
||||
IsArchived = 1 << 1,
|
||||
IsPasswordExpired = 1 << 2,
|
||||
// 1 << 3 was previously used in 0.x for the Linux compatibility mode, it should not be set in any 1.x+ databases.
|
||||
IsWhitelisted = 1 << 4,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ namespace MHServerEmu.DatabaseAccess.SQLite
|
|||
/// </summary>
|
||||
public class SQLiteDBManager : IDBManager
|
||||
{
|
||||
private const int CurrentSchemaVersion = 5; // Increment this when making changes to the database schema
|
||||
private const int CurrentSchemaVersion = 6; // Increment this when making changes to the database schema
|
||||
private const int MinimumSchemaVersion = 6; // Used to ignore legacy 0.x database files.
|
||||
private const int NumTestAccounts = 5; // Number of test accounts to create for new database files
|
||||
private const int NumPlayerDataWriteAttempts = 3; // Number of write attempts to do when saving player data
|
||||
|
||||
|
|
@ -397,6 +398,18 @@ namespace MHServerEmu.DatabaseAccess.SQLite
|
|||
if (schemaVersion > CurrentSchemaVersion)
|
||||
return Logger.ErrorReturn(false, $"Initialize(): Existing database file uses unsupported schema version {schemaVersion} (current = {CurrentSchemaVersion})");
|
||||
|
||||
if (schemaVersion < MinimumSchemaVersion)
|
||||
{
|
||||
Logger.Warn($"Found existing database file with legacy schema version {schemaVersion}, which is not supported by this version of MHServerEmu");
|
||||
|
||||
// Need to dispose the connection before moving the database file so that the file is not in use.
|
||||
connection.Dispose();
|
||||
File.Move(_dbFilePath, $"{_dbFilePath}.old");
|
||||
|
||||
InitializeDatabaseFile();
|
||||
return true;
|
||||
}
|
||||
|
||||
Logger.Info($"Found existing database file with schema version {schemaVersion} (current = {CurrentSchemaVersion})");
|
||||
|
||||
if (schemaVersion == CurrentSchemaVersion)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
-- Initialize a new database file using the current schema version
|
||||
|
||||
PRAGMA user_version=5;
|
||||
PRAGMA user_version=6;
|
||||
PRAGMA journal_mode=WAL;
|
||||
|
||||
CREATE TABLE "Account" (
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
-- Empty version, this is used only to prevent 0.x database files from being loaded in 1.x+.
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<AssemblyVersion>0.8.1.0</AssemblyVersion>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
<FileVersion>$(AssemblyVersion)</FileVersion>
|
||||
<InformationalVersion>$(AssemblyVersion)</InformationalVersion>
|
||||
</PropertyGroup>
|
||||
|
|
|
|||
|
|
@ -7,15 +7,18 @@ namespace MHServerEmu.Games
|
|||
public int AutosaveIntervalMinutes { get; private set; } = 15;
|
||||
public float ESCooldownOverrideMinutes { get; private set; } = -1f;
|
||||
public bool CombineESStacks { get; private set; } = false;
|
||||
public bool AutoUnlockAvatars { get; private set; } = true;
|
||||
public bool AutoUnlockTeamUps { get; private set; } = true;
|
||||
public bool AutoUnlockAvatars { get; private set; } = false;
|
||||
public bool AutoUnlockTeamUps { get; private set; } = false;
|
||||
public bool DisableMovementPowerChargeCost { get; private set; } = false;
|
||||
public bool AllowSameGroupTalents { get; private set; } = false;
|
||||
public bool EnableCreditChestConversion { get; private set; } = false;
|
||||
public float CreditChestConversionMultiplier { get; private set; } = 2f;
|
||||
public bool DisableInstancedLoot { get; private set; } = false;
|
||||
public float LootSpawnGridCellRadius { get; private set; } = 20f;
|
||||
public float TrashedItemExpirationTimeMultiplier { get; private set; } = 1f;
|
||||
public bool DisableAccountBinding { get; private set; } = false;
|
||||
public bool DisableCharacterBinding { get; private set; } = true;
|
||||
public bool DisableCharacterBinding { get; private set; } = false;
|
||||
public bool DisableMissionXPBonuses { get; private set; } = false;
|
||||
public bool UsePrestigeLootTable { get; private set; } = false;
|
||||
public bool EnableUltimatePrestige { get; private set; } = false;
|
||||
public bool ApplyHiddenPvPDamageModifiers { get; private set; } = false;
|
||||
|
|
|
|||
|
|
@ -1,134 +1,4 @@
|
|||
[
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_VendorBuyPrice",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_VendorSellPrice",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_VendorXPGain",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_PVPEnabled",
|
||||
"Value": 0.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_XPGain",
|
||||
"Value": 1.5
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_LootDropRate",
|
||||
"Value": 1.5
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_LootSpecialDropRate",
|
||||
"Value": 1.5
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_LootRarity",
|
||||
"Value": 1.5
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_PartyXPBonusPct",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_PlayerTradeEnabled",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_CosmicPrestigeXPPct",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_LootVaporizationEnabled",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_XPBuffDisplay",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_SIFBuffDisplay",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_RIFBuffDisplay",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_OmegaXPPct",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_RespectLevelForGlobalXP",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_RespectLevelForGlobalRIF",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_RespectLevelForGlobalSIF",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_RespectLevelForOmegaXP",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_RespectLevelForAvatarXP",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_RespectLevelForRegionXP",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_ServerBonusUnlockLevelOverride",
|
||||
"Value": 0.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_BoostTimersRunning",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_InfinityXPPct",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_RespectLevelForInfinityXP",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "Powers/EnemyPowers/Boss/MindlessOneBoss/GroundStomp.prototype",
|
||||
"Setting": "ePTV_PowerDamagePVE",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,132 @@
|
|||
[
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_VendorBuyPrice",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_VendorSellPrice",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_VendorXPGain",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_PVPEnabled",
|
||||
"Value": 0.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_XPGain",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_LootDropRate",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_LootSpecialDropRate",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_LootRarity",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_PartyXPBonusPct",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_PlayerTradeEnabled",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_CosmicPrestigeXPPct",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_LootVaporizationEnabled",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_XPBuffDisplay",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_SIFBuffDisplay",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_RIFBuffDisplay",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_OmegaXPPct",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_RespectLevelForGlobalXP",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_RespectLevelForGlobalRIF",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_RespectLevelForGlobalSIF",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_RespectLevelForOmegaXP",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_RespectLevelForAvatarXP",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_RespectLevelForRegionXP",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_ServerBonusUnlockLevelOverride",
|
||||
"Value": 0.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_BoostTimersRunning",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_InfinityXPPct",
|
||||
"Value": 1.0
|
||||
},
|
||||
{
|
||||
"Prototype": "",
|
||||
"Setting": "eGTV_RespectLevelForInfinityXP",
|
||||
"Value": 1.0
|
||||
}
|
||||
]
|
||||
|
|
@ -219,8 +219,7 @@ namespace MHServerEmu.Games.Entities.Avatars
|
|||
// Custom data
|
||||
if (archive.IsPersistent)
|
||||
{
|
||||
if (archive.Version >= ArchiveVersion.AddedUltimatePrestigeLevel)
|
||||
success &= Serializer.Transfer(archive, ref _ultimatePrestigeLevel);
|
||||
success &= Serializer.Transfer(archive, ref _ultimatePrestigeLevel);
|
||||
}
|
||||
|
||||
return success;
|
||||
|
|
@ -4717,6 +4716,9 @@ namespace MHServerEmu.Games.Entities.Avatars
|
|||
if (IsInWorld == false)
|
||||
return 0f;
|
||||
|
||||
if (Game.CustomGameOptions.DisableMissionXPBonuses)
|
||||
return 1f;
|
||||
|
||||
TuningPrototype tuningProto = tuningTable.Prototype;
|
||||
if (tuningProto == null) return Logger.WarnReturn(0f, "GetMissionXPMultiplier(): tuningProto == null");
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ namespace MHServerEmu.Games.Entities
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (archive.IsPersistent && archive.Version >= ArchiveVersion.ImplementedConditionPersistence)
|
||||
else if (archive.IsPersistent)
|
||||
{
|
||||
uint numConditions = (uint)GetPersistentConditionCount();
|
||||
success &= Serializer.Transfer(archive, ref numConditions);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
using MHServerEmu.Core.Logging;
|
||||
using MHServerEmu.Core.Serialization;
|
||||
using MHServerEmu.Games.Entities.Avatars;
|
||||
using MHServerEmu.Games.Properties;
|
||||
|
||||
namespace MHServerEmu.Games.Entities.Persistence
|
||||
{
|
||||
|
|
@ -19,8 +17,8 @@ namespace MHServerEmu.Games.Entities.Persistence
|
|||
|
||||
switch (loadedVersion)
|
||||
{
|
||||
// add versioning code here as needed
|
||||
case ArchiveVersion.Initial:
|
||||
success |= V2_ClearProperties(player);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -33,25 +31,5 @@ namespace MHServerEmu.Games.Entities.Persistence
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
#region V2
|
||||
|
||||
private static bool V2_ClearProperties(Player player)
|
||||
{
|
||||
player.Properties.RemovePropertyRange(PropertyEnum.Waypoint);
|
||||
player.Properties.RemovePropertyRange(PropertyEnum.UISystemLock);
|
||||
|
||||
// Team-ups seem to be invisible if they are summoned before the tutorial starts, so just unsummon them for all avatars
|
||||
foreach (Avatar avatar in new AvatarIterator(player))
|
||||
{
|
||||
avatar.Properties.RemoveProperty(PropertyEnum.AvatarTeamUpIsSummoned);
|
||||
avatar.Properties.RemoveProperty(PropertyEnum.AvatarTeamUpStartTime);
|
||||
avatar.Properties.RemoveProperty(PropertyEnum.AvatarTeamUpDuration);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -403,8 +403,7 @@ namespace MHServerEmu.Games.Entities
|
|||
|
||||
bool success = base.Serialize(archive);
|
||||
|
||||
if (archive.Version >= ArchiveVersion.AddedMissions)
|
||||
success &= Serializer.Transfer(archive, MissionManager);
|
||||
success &= Serializer.Transfer(archive, MissionManager);
|
||||
|
||||
success &= Serializer.Transfer(archive, ref _avatarProperties);
|
||||
|
||||
|
|
@ -455,39 +454,34 @@ namespace MHServerEmu.Games.Entities
|
|||
|
||||
if (archive.InvolvesClient == false)
|
||||
{
|
||||
if (archive.Version >= ArchiveVersion.ImplementedMapDiscoveryDataPersistence)
|
||||
success &= Serializer.Transfer(archive, ref _mapDiscoveryDict);
|
||||
success &= Serializer.Transfer(archive, ref _mapDiscoveryDict);
|
||||
|
||||
if (archive.Version >= ArchiveVersion.AddedVendorPurchaseData)
|
||||
// Vendor purchase data
|
||||
uint numVendorPurchaseData = (uint)_vendorPurchaseDataDict.Count;
|
||||
success &= Serializer.Transfer(archive, ref numVendorPurchaseData);
|
||||
|
||||
if (archive.IsPacking)
|
||||
{
|
||||
uint numVendorPurchaseData = (uint)_vendorPurchaseDataDict.Count;
|
||||
success &= Serializer.Transfer(archive, ref numVendorPurchaseData);
|
||||
foreach (VendorPurchaseData purchaseData in _vendorPurchaseDataDict.Values)
|
||||
success &= Serializer.Transfer(archive, purchaseData);
|
||||
}
|
||||
else
|
||||
{
|
||||
_vendorPurchaseDataDict.Clear();
|
||||
|
||||
if (archive.IsPacking)
|
||||
for (uint i = 0; i < numVendorPurchaseData; i++)
|
||||
{
|
||||
foreach (VendorPurchaseData purchaseData in _vendorPurchaseDataDict.Values)
|
||||
success &= Serializer.Transfer(archive, purchaseData);
|
||||
}
|
||||
else
|
||||
{
|
||||
_vendorPurchaseDataDict.Clear();
|
||||
VendorPurchaseData purchaseData = new(PrototypeId.Invalid);
|
||||
success &= Serializer.Transfer(archive, ref purchaseData);
|
||||
|
||||
for (uint i = 0; i < numVendorPurchaseData; i++)
|
||||
{
|
||||
VendorPurchaseData purchaseData = new(PrototypeId.Invalid);
|
||||
success &= Serializer.Transfer(archive, ref purchaseData);
|
||||
|
||||
if (_vendorPurchaseDataDict.TryAdd(purchaseData.InventoryProtoRef, purchaseData) == false)
|
||||
Logger.Warn($"Serialize(): Failed to add deserialized vendor purchase data {purchaseData}");
|
||||
}
|
||||
if (_vendorPurchaseDataDict.TryAdd(purchaseData.InventoryProtoRef, purchaseData) == false)
|
||||
Logger.Warn($"Serialize(): Failed to add deserialized vendor purchase data {purchaseData}");
|
||||
}
|
||||
}
|
||||
|
||||
if (archive.Version >= ArchiveVersion.ImplementedLoginRewards)
|
||||
{
|
||||
success &= Serializer.Transfer(archive, ref _loginCount);
|
||||
success &= Serializer.Transfer(archive, ref _loginRewardCooldownTimeStart);
|
||||
}
|
||||
// Login count
|
||||
success &= Serializer.Transfer(archive, ref _loginCount);
|
||||
success &= Serializer.Transfer(archive, ref _loginRewardCooldownTimeStart);
|
||||
}
|
||||
|
||||
return success;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ namespace MHServerEmu.Games.Events
|
|||
{
|
||||
public class Event
|
||||
{
|
||||
public const int InfiniteLoopCheckLimit = 5000; // in client 100000
|
||||
public const int InfiniteLoopCheckLimit = 100000;
|
||||
|
||||
private static readonly Logger Logger = LogManager.CreateLogger();
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<InformationalVersion>0.8.1</InformationalVersion>
|
||||
<InformationalVersion>1.0.0</InformationalVersion>
|
||||
<SourceRevisionId>build$([System.DateTime]::UtcNow.ToString("yyyyMMddHHmmss"))</SourceRevisionId>
|
||||
<AssemblyVersion>$(InformationalVersion).0</AssemblyVersion>
|
||||
<FileVersion>$(AssemblyVersion)</FileVersion>
|
||||
|
|
@ -67,6 +67,9 @@
|
|||
<None Update="Data\Game\Achievements\Off\AchievementStringMap_05_Collection.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Data\Game\LiveTuning\LiveTuningData.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Data\Game\LiveTuning\LiveTuningDataPvP.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
|
|
@ -103,7 +106,7 @@
|
|||
<None Update="Data\Game\Patches\PatchDataBugFixes.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Data\Game\LiveTuning\LiveTuningData.json">
|
||||
<None Update="Data\Game\LiveTuning\LiveTuningDataGlobal.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Data\Game\LiveTuning\LiveTuningDataBugFixes.json">
|
||||
|
|
|
|||
|
|
@ -771,9 +771,9 @@ namespace MHServerEmu.Games.Properties
|
|||
|
||||
if (archive.IsPacking)
|
||||
{
|
||||
// NOTE: PropertyCollection::serializeWithDefault() does a weird thing where it manipulates the archive buffer directly.
|
||||
// First it allocates 4 bytes for the number of properties, than it writes all the properties, and then it goes back
|
||||
// and updates the number.
|
||||
// NOTE: PropertyCollection::serializeWithDefault() manipulates the archive buffer directly.
|
||||
// It allocates 4 bytes for the number of properties, writes all the properties, and then
|
||||
// it goes back and updates the number.
|
||||
|
||||
// Remember current offset and reserve 4 bytes
|
||||
long numPropertiesOffset = archive.CurrentOffset;
|
||||
|
|
@ -785,7 +785,7 @@ namespace MHServerEmu.Games.Properties
|
|||
success &= SerializePropertyForPacking(kvp, ref numProperties, archive, defaultCollection);
|
||||
|
||||
// Write the number of serialized properties to the reserved bytes
|
||||
archive.WriteUnencodedStream(numProperties, numPropertiesOffset);
|
||||
archive.WriteUnencodedStream(numProperties, numPropertiesOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -41,9 +41,7 @@ namespace MHServerEmu.Games.Regions.Maps
|
|||
bool success = true;
|
||||
|
||||
success &= Serializer.Transfer(archive, ref _regionId);
|
||||
|
||||
if (archive.Version >= ArchiveVersion.AddedRegionProtoRefToMapDiscoveryData)
|
||||
success &= Serializer.Transfer(archive, ref _regionProtoRef);
|
||||
success &= Serializer.Transfer(archive, ref _regionProtoRef);
|
||||
|
||||
success &= Serializer.Transfer(archive, ref _accessTimestamp);
|
||||
success &= Serializer.Transfer(archive, ref _discoveredEntities);
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<AssemblyVersion>0.8.1.0</AssemblyVersion>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
<FileVersion>$(AssemblyVersion)</FileVersion>
|
||||
<InformationalVersion>$(AssemblyVersion)</InformationalVersion>
|
||||
</PropertyGroup>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<AssemblyVersion>0.8.1.0</AssemblyVersion>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
<FileVersion>$(AssemblyVersion)</FileVersion>
|
||||
<InformationalVersion>$(AssemblyVersion)</InformationalVersion>
|
||||
</PropertyGroup>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<AssemblyVersion>0.8.1.0</AssemblyVersion>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
<FileVersion>$(AssemblyVersion)</FileVersion>
|
||||
<InformationalVersion>$(AssemblyVersion)</InformationalVersion>
|
||||
</PropertyGroup>
|
||||
|
|
|
|||
|
|
@ -102,6 +102,9 @@ namespace MHServerEmu.PlayerManagement.Matchmaking
|
|||
if (IsFull() == false && IsBypass == false && Queue.Prototype.QueueDoNotWaitToFull == false)
|
||||
return false;
|
||||
|
||||
if (IsEmpty())
|
||||
return false;
|
||||
|
||||
foreach (MatchTeam team in _teams)
|
||||
{
|
||||
foreach ((RegionRequestGroup group, _) in team.Groups)
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ namespace MHServerEmu.WebFrontend.Handlers
|
|||
".jpeg" => "image/jpeg",
|
||||
".gif" => "image/gif",
|
||||
".ico" => "image/x-icon",
|
||||
".xml" => "application/xml",
|
||||
".json" => "application/json",
|
||||
_ => "application/octet-stream",
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<AssemblyVersion>0.8.1.0</AssemblyVersion>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
<FileVersion>$(AssemblyVersion)</FileVersion>
|
||||
<InformationalVersion>$(AssemblyVersion)</InformationalVersion>
|
||||
</PropertyGroup>
|
||||
|
|
|
|||
|
|
@ -147,29 +147,37 @@ namespace MHServerEmu.Commands.Implementations
|
|||
}
|
||||
|
||||
[Command("creditchest")]
|
||||
[CommandDescription("Converts 500k credits to a sellable chest item.")]
|
||||
[CommandDescription("Converts credits to a sellable chest item.")]
|
||||
[CommandUsage("item creditchest")]
|
||||
[CommandInvokerType(CommandInvokerType.Client)]
|
||||
public string CreditChest(string[] @params, NetClient client)
|
||||
{
|
||||
const PrototypeId CreditItemProtoRef = (PrototypeId)13983056721138685632;
|
||||
const PrototypeId CreditItemProtoRef = (PrototypeId)13983056721138685632; // Entity/Items/Crafting/Ingredients/CreditItem500k.prototype
|
||||
const int CreditItemPrice = 500000;
|
||||
|
||||
PlayerConnection playerConnection = (PlayerConnection)client;
|
||||
Player player = playerConnection.Player;
|
||||
|
||||
var options = player.Game.CustomGameOptions;
|
||||
|
||||
if (options.EnableCreditChestConversion == false)
|
||||
return "Credit chest conversion is disabled by server settings";
|
||||
|
||||
PropertyId creditsProperty = new(PropertyEnum.Currency, GameDatabase.CurrencyGlobalsPrototype.Credits);
|
||||
int price = (int)(CreditItemPrice * options.CreditChestConversionMultiplier);
|
||||
|
||||
if (player.Properties[creditsProperty] < CreditItemPrice)
|
||||
return "You need at least 500 000 credits to use this command.";
|
||||
if (price <= 0)
|
||||
return "Failed to calculate credit chest price.";
|
||||
|
||||
// Entity/Items/Crafting/Ingredients/CreditItem500k.prototype
|
||||
player.Properties.AdjustProperty(-CreditItemPrice, creditsProperty);
|
||||
if (player.Properties[creditsProperty] < price)
|
||||
return $"You need at least {price} credits to use this command.";
|
||||
|
||||
player.Properties.AdjustProperty(-price, creditsProperty);
|
||||
player.Game.LootManager.GiveItem(CreditItemProtoRef, LootContext.CashShop, player);
|
||||
|
||||
Logger.Trace($"CreditChest(): {player}");
|
||||
|
||||
return $"Converted 500 000 credits to a Credit Chest.";
|
||||
return $"Converted {price} credits to a Credit Chest.";
|
||||
}
|
||||
|
||||
[Command("cleardeliverybox")]
|
||||
|
|
|
|||
|
|
@ -118,11 +118,17 @@ namespace MHServerEmu.Commands.Implementations
|
|||
[CommandInvokerType(CommandInvokerType.Client)]
|
||||
public string Dance(string[] @params, NetClient client)
|
||||
{
|
||||
PlayerConnection playerConnection = (PlayerConnection)client;
|
||||
const PrototypeId DancePowerRef = (PrototypeId)773103106671775187; // Powers/Emotes/EmoteDance.prototype
|
||||
|
||||
Avatar avatar = playerConnection.Player.CurrentAvatar;
|
||||
var avatarPrototypeId = (AvatarPrototypeId)avatar.PrototypeDataRef;
|
||||
switch (avatarPrototypeId)
|
||||
Player player = ((PlayerConnection)client).Player;
|
||||
Avatar avatar = player.CurrentAvatar;
|
||||
|
||||
if (avatar == null)
|
||||
return string.Empty;
|
||||
|
||||
PrototypeId avatarProtoRef = avatar.PrototypeDataRef;
|
||||
|
||||
switch ((AvatarPrototypeId)avatarProtoRef)
|
||||
{
|
||||
case AvatarPrototypeId.BlackPanther:
|
||||
case AvatarPrototypeId.BlackWidow:
|
||||
|
|
@ -137,18 +143,20 @@ namespace MHServerEmu.Commands.Implementations
|
|||
case AvatarPrototypeId.Storm:
|
||||
case AvatarPrototypeId.Thing:
|
||||
case AvatarPrototypeId.Thor:
|
||||
const PrototypeId dancePowerRef = (PrototypeId)773103106671775187; // Powers/Emotes/EmoteDance.prototype
|
||||
|
||||
Power dancePower = avatar.GetPower(dancePowerRef);
|
||||
if (dancePower == null) return "Dance power is not assigned to the current avatar.";
|
||||
if (player.HasAvatarEmoteUnlocked(avatarProtoRef, DancePowerRef) == false)
|
||||
player.UnlockAvatarEmote(avatarProtoRef, DancePowerRef);
|
||||
|
||||
PowerActivationSettings settings = new(avatar.Id, avatar.RegionLocation.Position, avatar.RegionLocation.Position);
|
||||
settings.Flags = PowerActivationSettingsFlags.NotifyOwner;
|
||||
avatar.ActivatePower(dancePowerRef, ref settings);
|
||||
PowerUseResult result = avatar.ActivatePower(DancePowerRef, ref settings);
|
||||
|
||||
if (result != PowerUseResult.Success)
|
||||
return $"Failed to activate dance power ({result}).";
|
||||
|
||||
return $"{avatarProtoRef.GetNameFormatted()} begins to dance.";
|
||||
|
||||
return $"{avatarPrototypeId} begins to dance";
|
||||
default:
|
||||
return $"{avatarPrototypeId} doesn't want to dance";
|
||||
return $"{avatarProtoRef.GetNameFormatted()} doesn't want to dance.";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ PlayerName=Player
|
|||
|
||||
ServerName=MHServerEmu
|
||||
ServerPrestigeLevel=6
|
||||
MotdText=Welcome back to Marvel Heroes! Type !commands to see a list of available server commands.
|
||||
MotdText=Welcome to Marvel Heroes! Type !commands for a list of available server commands.
|
||||
LogPrivateChatRooms=false
|
||||
EnableChatTips=false
|
||||
ChatTipFileName=ChatTips.txt
|
||||
|
|
@ -197,11 +197,14 @@ OrbisTrophiesEnabled=true
|
|||
; AutoUnlockTeamUps: Automatically unlocks all team-ups for players who have finished the tutorial.
|
||||
; DisableMovementPowerChargeCost: Disables charge costs for movement powers to imitate pre-BUE behavior.
|
||||
; AllowSameGroupTalents: Allows mutually exclusive talents to be enabled at the same time.
|
||||
; EnableCreditChestConversion: Allows conversion of credits to sellable chest items via the !item creditchest command.
|
||||
; CreditChestConversionMultiplier: Cost multiplier for converting credits to chest items.
|
||||
; DisableInstancedLoot: Makes loot free-for-all, Diablo 2 style.
|
||||
; LootSpawnGridCellRadius: Affects the spacing of loot that drops [16-128].
|
||||
; TrashedItemExpirationTimeMultiplier: Affects how long items trashed by players remain on the ground.
|
||||
; DisableAccountBinding: Disables account binding on pickup for items.
|
||||
; DisableCharacterBinding: Disables character binding on equip for items.
|
||||
; DisableMissionXPBonuses: Prevents mission experience rewards from being affected by experience bonuses.
|
||||
; UsePrestigeLootTable: Replaces starting costume prestige rewards with the loot table specified in game data.
|
||||
; EnableUltimatePrestige: Allows prestige level to be reset after reaching the prestige level cap.
|
||||
; ApplyHiddenPvPDamageModifiers: Enables hidden damage modifiers based on K/D ratio, match history, and Omega level in PvP combat.
|
||||
|
|
@ -209,15 +212,18 @@ OrbisTrophiesEnabled=true
|
|||
AutosaveIntervalMinutes=15
|
||||
ESCooldownOverrideMinutes=-1.0
|
||||
CombineESStacks=false
|
||||
AutoUnlockAvatars=true
|
||||
AutoUnlockTeamUps=true
|
||||
AutoUnlockAvatars=false
|
||||
AutoUnlockTeamUps=false
|
||||
DisableMovementPowerChargeCost=false
|
||||
AllowSameGroupTalents=false
|
||||
EnableCreditChestConversion=false
|
||||
CreditChestConversionMultiplier=2.0
|
||||
DisableInstancedLoot=false
|
||||
LootSpawnGridCellRadius=20.0
|
||||
TrashedItemExpirationTimeMultiplier=1.0
|
||||
DisableAccountBinding=false
|
||||
DisableCharacterBinding=false
|
||||
DisableMissionXPBonuses=false
|
||||
UsePrestigeLootTable=false
|
||||
EnableUltimatePrestige=false
|
||||
ApplyHiddenPvPDamageModifiers=false
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<InformationalVersion>0.8.1</InformationalVersion>
|
||||
<InformationalVersion>1.0.0</InformationalVersion>
|
||||
<SourceRevisionId>build$([System.DateTime]::UtcNow.ToString("yyyyMMddHHmmss"))</SourceRevisionId>
|
||||
<AssemblyVersion>$(InformationalVersion).0</AssemblyVersion>
|
||||
<FileVersion>$(AssemblyVersion)</FileVersion>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue