Use generated structs where possible

This commit is contained in:
Garry Newman 2016-10-29 20:50:40 +01:00
parent 94e661c6b0
commit 778faa1049
14 changed files with 55 additions and 199 deletions

View File

@ -5,14 +5,6 @@ using System.Text;
namespace Facepunch.Steamworks.Callbacks namespace Facepunch.Steamworks.Callbacks
{ {
internal static class Index
{
internal const int User = 100;
internal const int Networking = 1200;
internal const int RemoteStorage = 1300;
internal const int UGC = 3400;
}
public enum Result : int public enum Result : int
{ {
OK = 1, // success OK = 1, // success

View File

@ -1,27 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace Facepunch.Steamworks.Callbacks.Networking
{
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
internal class P2PSessionRequest
{
public ulong SteamID;
public const int CallbackId = Index.Networking + 2;
};
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
internal class P2PSessionConnectFail
{
public ulong SteamID;
public Steamworks.Networking.SessionError Error;
public const int CallbackId = Index.Networking + 3;
};
}

View File

@ -1,34 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace Facepunch.Steamworks.Callbacks.User
{
[StructLayout( LayoutKind.Sequential, Pack = 4 )]
internal struct ValidateAuthTicketResponse
{
public ulong SteamID;
public int AuthResponse;
public ulong OwnerSteamID;
public const int CallbackId = Index.User + 43;
public enum Response : int
{
Okay = 0, // Steam has verified the user is online, the ticket is valid and ticket has not been reused.
UserNotConnectedToSteam = 1, // The user in question is not connected to steam
NoLicenseOrExpired = 2, // The license has expired.
VACBanned = 3, // The user is VAC banned for this game.
LoggedInElseWhere = 4, // The user account has logged in elsewhere and the session containing the game instance has been disconnected.
VACCheckTimedOut = 5, // VAC has been unable to perform anti-cheat checks on this user
AuthTicketCanceled = 6, // The ticket has been canceled by the issuer
AuthTicketInvalidAlreadyUsed = 7, // This ticket has already been used, it is not valid.
AuthTicketInvalid = 8, // This ticket is not from a user instance currently connected to steam.
PublisherIssuedBan = 9, // The user is banned for this game. The ban came via the web api and not VAC
};
};
}

View File

@ -3,14 +3,13 @@ using Facepunch.Steamworks.Interop;
namespace Facepunch.Steamworks.Callbacks.Workshop namespace Facepunch.Steamworks.Callbacks.Workshop
{ {
[StructLayout( LayoutKind.Sequential, Pack = 8 )] [StructLayout( LayoutKind.Sequential, Pack = 8 )]
internal struct ItemInstalled internal struct ItemInstalled
{ {
public uint AppId; public uint AppId;
public ulong FileId; public ulong FileId;
public const int CallbackId = Index.UGC + 5; public const int CallbackId = SteamNative.CallbackIdentifiers.ClientUGC + 5;
[StructLayout( LayoutKind.Sequential, Pack = 4 )] [StructLayout( LayoutKind.Sequential, Pack = 4 )]
internal struct Small internal struct Small
@ -20,90 +19,20 @@ namespace Facepunch.Steamworks.Callbacks.Workshop
}; };
}; };
[StructLayout( LayoutKind.Sequential, Pack = 8 )] internal class QueryCompleted : CallResult<SteamNative.SteamUGCQueryCompleted_t, SteamNative.SteamUGCQueryCompleted_t.PackSmall>
internal struct DownloadResult
{ {
public uint AppId; public override int CallbackId { get { return SteamNative.SteamUGCQueryCompleted_t.CallbackId; } }
public ulong FileId;
public Result Result;
public const int CallbackId = Index.UGC + 6;
[StructLayout( LayoutKind.Sequential, Pack = 4 )]
internal struct Small
{
public uint AppId;
public ulong FileId;
public Result Result;
};
};
internal class QueryCompleted : CallResult<QueryCompleted.Data, QueryCompleted.Data.Small>
{
public override int CallbackId { get { return Index.UGC + 1; } }
[StructLayout( LayoutKind.Sequential, Pack = 8 )]
internal struct Data
{
internal ulong Handle;
internal int Result;
internal uint NumResultsReturned;
internal uint TotalMatchingResults;
internal bool CachedData;
[StructLayout( LayoutKind.Sequential, Pack = 4 )]
internal struct Small
{
internal ulong Handle;
internal int Result;
internal uint NumResultsReturned;
internal uint TotalMatchingResults;
internal bool CachedData;
};
};
} }
internal class CreateItem : CallResult<CreateItem.Data, CreateItem.Data.Small> internal class CreateItem : CallResult<SteamNative.CreateItemResult_t, SteamNative.CreateItemResult_t.PackSmall>
{ {
public override int CallbackId { get { return Index.UGC + 3; } } public override int CallbackId { get { return SteamNative.CreateItemResult_t.CallbackId; } }
[StructLayout( LayoutKind.Sequential, Pack = 8 )]
internal struct Data
{
internal Result Result;
internal ulong FileId;
internal bool NeedsLegalAgreement;
[StructLayout( LayoutKind.Sequential, Pack = 4 )]
internal struct Small
{
internal Result Result;
internal ulong FileId;
internal bool NeedsLegalAgreement;
};
};
} }
internal class SubmitItemUpdate : CallResult<SubmitItemUpdate.Data, SubmitItemUpdate.Data.Small> internal class SubmitItemUpdate : CallResult<SteamNative.SubmitItemUpdateResult_t, SteamNative.SubmitItemUpdateResult_t.PackSmall>
{ {
public override int CallbackId { get { return Index.UGC + 4; } } public override int CallbackId { get { return SteamNative.SubmitItemUpdateResult_t.CallbackId; } }
public SteamNative.UGCUpdateHandle_t UpdateHandle; public SteamNative.UGCUpdateHandle_t UpdateHandle;
[StructLayout( LayoutKind.Sequential, Pack = 8 )]
internal struct Data
{
internal Result Result;
internal bool NeedsLegalAgreement;
[StructLayout( LayoutKind.Sequential, Pack = 4 )]
internal struct Small
{
internal Result Result;
internal bool NeedsLegalAgreement;
};
};
} }
} }

View File

@ -114,7 +114,6 @@
<ItemGroup> <ItemGroup>
<Compile Include="BaseSteamworks.cs" /> <Compile Include="BaseSteamworks.cs" />
<Compile Include="Callbacks\Index.cs" /> <Compile Include="Callbacks\Index.cs" />
<Compile Include="Callbacks\User.cs" />
<Compile Include="Callbacks\Workshop.cs" /> <Compile Include="Callbacks\Workshop.cs" />
<Compile Include="Interfaces\Inventory.Item.cs" /> <Compile Include="Interfaces\Inventory.Item.cs" />
<Compile Include="Interfaces\Inventory.Result.cs" /> <Compile Include="Interfaces\Inventory.Result.cs" />
@ -134,7 +133,6 @@
<Compile Include="Interfaces\Inventory.Definition.cs" /> <Compile Include="Interfaces\Inventory.Definition.cs" />
<Compile Include="Client\Voice.cs" /> <Compile Include="Client\Voice.cs" />
<Compile Include="Config.cs" /> <Compile Include="Config.cs" />
<Compile Include="Callbacks\Networking.cs" />
<Compile Include="Interfaces\Workshop.cs" /> <Compile Include="Interfaces\Workshop.cs" />
<Compile Include="Interfaces\Workshop.Editor.cs" /> <Compile Include="Interfaces\Workshop.Editor.cs" />
<Compile Include="Interfaces\Workshop.Item.cs" /> <Compile Include="Interfaces\Workshop.Item.cs" />

View File

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Facepunch.Steamworks.Callbacks.Networking;
namespace Facepunch.Steamworks namespace Facepunch.Steamworks
{ {
@ -19,8 +18,8 @@ namespace Facepunch.Steamworks
{ {
this.networking = networking; this.networking = networking;
sw.AddCallback<P2PSessionRequest>( onP2PConnectionRequest, P2PSessionRequest.CallbackId ); sw.AddCallback<SteamNative.P2PSessionRequest_t>( onP2PConnectionRequest, SteamNative.P2PSessionRequest_t.CallbackId );
sw.AddCallback<P2PSessionConnectFail>( onP2PConnectionFailed, P2PSessionConnectFail.CallbackId ); sw.AddCallback<SteamNative.P2PSessionConnectFail_t>( onP2PConnectionFailed, SteamNative.P2PSessionConnectFail_t.CallbackId );
} }
public void Dispose() public void Dispose()
@ -47,19 +46,19 @@ namespace Facepunch.Steamworks
} }
} }
private void onP2PConnectionRequest( P2PSessionRequest o, bool b ) private void onP2PConnectionRequest( SteamNative.P2PSessionRequest_t o, bool b )
{ {
if ( OnIncomingConnection != null ) if ( OnIncomingConnection != null )
{ {
var accept = OnIncomingConnection( o.SteamID ); var accept = OnIncomingConnection( o.SteamIDRemote );
if ( accept ) if ( accept )
{ {
networking.AcceptP2PSessionWithUser( o.SteamID ); networking.AcceptP2PSessionWithUser( o.SteamIDRemote );
} }
else else
{ {
networking.CloseP2PSessionWithUser( o.SteamID ); networking.CloseP2PSessionWithUser( o.SteamIDRemote );
} }
return; return;
@ -68,7 +67,7 @@ namespace Facepunch.Steamworks
// //
// Default is to reject the session // Default is to reject the session
// //
networking.CloseP2PSessionWithUser( o.SteamID ); networking.CloseP2PSessionWithUser( o.SteamIDRemote );
} }
public enum SessionError : byte public enum SessionError : byte
@ -83,11 +82,11 @@ namespace Facepunch.Steamworks
Max = 5 Max = 5
}; };
private void onP2PConnectionFailed( P2PSessionConnectFail o, bool b ) private void onP2PConnectionFailed( SteamNative.P2PSessionConnectFail_t o, bool b )
{ {
if ( OnConnectionFailed != null ) if ( OnConnectionFailed != null )
{ {
OnConnectionFailed( o.SteamID, o.Error ); OnConnectionFailed( o.SteamIDRemote, (SessionError) o.P2PSessionError );
} }
} }

View File

@ -114,14 +114,14 @@ namespace Facepunch.Steamworks
workshop.steamworks.AddCallResult( CreateItem ); workshop.steamworks.AddCallResult( CreateItem );
} }
private void OnItemCreated( CreateItem.Data obj ) private void OnItemCreated( SteamNative.CreateItemResult_t obj )
{ {
NeedToAgreeToWorkshopLegal = obj.NeedsLegalAgreement; NeedToAgreeToWorkshopLegal = obj.UserNeedsToAcceptWorkshopLegalAgreement;
CreateItem = null; CreateItem = null;
if ( obj.Result == Callbacks.Result.OK ) if ( obj.Result == SteamNative.Result.OK )
{ {
Id = obj.FileId; Id = obj.PublishedFileId;
PublishChanges(); PublishChanges();
return; return;
} }
@ -171,13 +171,13 @@ namespace Facepunch.Steamworks
workshop.steamworks.AddCallResult( SubmitItemUpdate ); workshop.steamworks.AddCallResult( SubmitItemUpdate );
} }
private void OnChangesSubmitted( SubmitItemUpdate.Data obj ) private void OnChangesSubmitted( SteamNative.SubmitItemUpdateResult_t obj )
{ {
SubmitItemUpdate = null; SubmitItemUpdate = null;
NeedToAgreeToWorkshopLegal = obj.NeedsLegalAgreement; NeedToAgreeToWorkshopLegal = obj.UserNeedsToAcceptWorkshopLegalAgreement;
Publishing = false; Publishing = false;
if ( obj.Result == Callbacks.Result.OK ) if ( obj.Result == SteamNative.Result.OK )
{ {
return; return;
} }

View File

@ -4,7 +4,6 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using Facepunch.Steamworks.Callbacks.Networking;
using Facepunch.Steamworks.Callbacks.Workshop; using Facepunch.Steamworks.Callbacks.Workshop;
namespace Facepunch.Steamworks namespace Facepunch.Steamworks

View File

@ -114,7 +114,7 @@ namespace Facepunch.Steamworks
workshop.steamworks.AddCallResult( Callback ); workshop.steamworks.AddCallResult( Callback );
} }
void OnResult( QueryCompleted.Data data ) void OnResult( SteamNative.SteamUGCQueryCompleted_t data )
{ {
var gotFiles = 0; var gotFiles = 0;
for ( int i = 0; i < data.NumResultsReturned; i++ ) for ( int i = 0; i < data.NumResultsReturned; i++ )

View File

@ -22,8 +22,8 @@ namespace Facepunch.Steamworks
this.steamworks = steamworks; this.steamworks = steamworks;
this.remoteStorage = remoteStorage; this.remoteStorage = remoteStorage;
steamworks.AddCallback<DownloadResult, DownloadResult.Small>( onDownloadResult, DownloadResult.CallbackId ); steamworks.AddCallback<SteamNative.DownloadItemResult_t, SteamNative.DownloadItemResult_t.PackSmall>( onDownloadResult, SteamNative.DownloadItemResult_t.CallbackId );
steamworks.AddCallback<ItemInstalled, DownloadResult.Small>( onItemInstalled, ItemInstalled.CallbackId ); steamworks.AddCallback<ItemInstalled, ItemInstalled.Small>( onItemInstalled, ItemInstalled.CallbackId );
} }
public void Dispose() public void Dispose()
@ -43,10 +43,10 @@ namespace Facepunch.Steamworks
OnItemInstalled( obj.FileId ); OnItemInstalled( obj.FileId );
} }
private void onDownloadResult( DownloadResult obj, bool failed ) private void onDownloadResult( SteamNative.DownloadItemResult_t obj, bool failed )
{ {
if ( OnFileDownloaded != null ) if ( OnFileDownloaded != null )
OnFileDownloaded( obj.FileId, obj.Result ); OnFileDownloaded( obj.PublishedFileId, (Callbacks.Result) obj.Result );
} }
public Query CreateQuery() public Query CreateQuery()

View File

@ -2,7 +2,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Facepunch.Steamworks.Callbacks.User;
namespace Facepunch.Steamworks namespace Facepunch.Steamworks
{ {
@ -36,32 +35,29 @@ namespace Facepunch.Steamworks
/// </summary> /// </summary>
public enum Status : int public enum Status : int
{ {
/// <summary>
/// Steam has verified the user is online, the ticket is valid and ticket has not been reused.
/// </summary>
OK = 0, OK = 0,
UserNotConnectedToSteam = 1, // The user in question is not connected to steam UserNotConnectedToSteam = 1,
NoLicenseOrExpired = 2, // The license has expired. NoLicenseOrExpired = 2,
VACBanned = 3, // The user is VAC banned for this game. VACBanned = 3,
LoggedInElseWhere = 4, // The user account has logged in elsewhere and the session containing the game instance has been disconnected. LoggedInElseWhere = 4,
VACCheckTimedOut = 5, // VAC has been unable to perform anti-cheat checks on this user VACCheckTimedOut = 5,
AuthTicketCanceled = 6, // The ticket has been canceled by the issuer AuthTicketCanceled = 6,
AuthTicketInvalidAlreadyUsed = 7, // This ticket has already been used, it is not valid. AuthTicketInvalidAlreadyUsed = 7,
AuthTicketInvalid = 8, // This ticket is not from a user instance currently connected to steam. AuthTicketInvalid = 8,
PublisherIssuedBan = 9, // The user is banned for this game. The ban came via the web api and not VAC PublisherIssuedBan = 9,
} }
internal ServerAuth( Server s ) internal ServerAuth( Server s )
{ {
server = s; server = s;
server.AddCallback<ValidateAuthTicketResponse>( OnAuthTicketValidate, ValidateAuthTicketResponse.CallbackId ); server.AddCallback<SteamNative.ValidateAuthTicketResponse_t>( OnAuthTicketValidate, SteamNative.ValidateAuthTicketResponse_t.CallbackId );
} }
void OnAuthTicketValidate( ValidateAuthTicketResponse data, bool b ) void OnAuthTicketValidate( SteamNative.ValidateAuthTicketResponse_t data, bool b )
{ {
if ( OnAuthChange != null ) if ( OnAuthChange != null )
OnAuthChange( data.SteamID, data.OwnerSteamID, (Status) data.AuthResponse ); OnAuthChange( data.SteamID, data.OwnerSteamID, (Status) data.AuthSessionResponse );
} }
/// <summary> /// <summary>

View File

@ -4651,6 +4651,7 @@ namespace SteamNative
[StructLayout( LayoutKind.Sequential, Pack = 4 )] [StructLayout( LayoutKind.Sequential, Pack = 4 )]
public struct P2PSessionRequest_t public struct P2PSessionRequest_t
{ {
public const int CallbackId = CallbackIdentifiers.SteamNetworking + 2;
public ulong SteamIDRemote; // m_steamIDRemote class CSteamID public ulong SteamIDRemote; // m_steamIDRemote class CSteamID
// //
@ -4690,6 +4691,7 @@ namespace SteamNative
[StructLayout( LayoutKind.Sequential, Pack = 4 )] [StructLayout( LayoutKind.Sequential, Pack = 4 )]
public struct P2PSessionConnectFail_t public struct P2PSessionConnectFail_t
{ {
public const int CallbackId = CallbackIdentifiers.SteamNetworking + 3;
public ulong SteamIDRemote; // m_steamIDRemote class CSteamID public ulong SteamIDRemote; // m_steamIDRemote class CSteamID
public byte P2PSessionError; // m_eP2PSessionError uint8 public byte P2PSessionError; // m_eP2PSessionError uint8
@ -4732,6 +4734,7 @@ namespace SteamNative
[StructLayout( LayoutKind.Sequential, Pack = 4 )] [StructLayout( LayoutKind.Sequential, Pack = 4 )]
public struct SocketStatusCallback_t public struct SocketStatusCallback_t
{ {
public const int CallbackId = CallbackIdentifiers.SteamNetworking + 1;
public uint Socket; // m_hSocket SNetSocket_t public uint Socket; // m_hSocket SNetSocket_t
public uint ListenSocket; // m_hListenSocket SNetListenSocket_t public uint ListenSocket; // m_hListenSocket SNetListenSocket_t
public ulong SteamIDRemote; // m_steamIDRemote class CSteamID public ulong SteamIDRemote; // m_steamIDRemote class CSteamID
@ -5588,7 +5591,7 @@ namespace SteamNative
public struct SteamUGCQueryCompleted_t public struct SteamUGCQueryCompleted_t
{ {
public const int CallbackId = CallbackIdentifiers.ClientUGC + 1; public const int CallbackId = CallbackIdentifiers.ClientUGC + 1;
public ulong Andle; // m_handle UGCQueryHandle_t public ulong Handle; // m_handle UGCQueryHandle_t
public Result Result; // m_eResult enum EResult public Result Result; // m_eResult enum EResult
public uint NumResultsReturned; // m_unNumResultsReturned uint32 public uint NumResultsReturned; // m_unNumResultsReturned uint32
public uint TotalMatchingResults; // m_unTotalMatchingResults uint32 public uint TotalMatchingResults; // m_unTotalMatchingResults uint32
@ -5606,7 +5609,7 @@ namespace SteamNative
[StructLayout( LayoutKind.Sequential, Pack = 4 )] [StructLayout( LayoutKind.Sequential, Pack = 4 )]
public struct PackSmall public struct PackSmall
{ {
public ulong Andle; // m_handle UGCQueryHandle_t public ulong Handle; // m_handle UGCQueryHandle_t
public Result Result; // m_eResult enum EResult public Result Result; // m_eResult enum EResult
public uint NumResultsReturned; // m_unNumResultsReturned uint32 public uint NumResultsReturned; // m_unNumResultsReturned uint32
public uint TotalMatchingResults; // m_unTotalMatchingResults uint32 public uint TotalMatchingResults; // m_unTotalMatchingResults uint32
@ -5620,7 +5623,7 @@ namespace SteamNative
{ {
return new SteamUGCQueryCompleted_t() return new SteamUGCQueryCompleted_t()
{ {
Andle = d.Andle, Handle = d.Handle,
Result = d.Result, Result = d.Result,
NumResultsReturned = d.NumResultsReturned, NumResultsReturned = d.NumResultsReturned,
TotalMatchingResults = d.TotalMatchingResults, TotalMatchingResults = d.TotalMatchingResults,
@ -7233,7 +7236,7 @@ namespace SteamNative
public struct SteamInventoryResultReady_t public struct SteamInventoryResultReady_t
{ {
public const int CallbackId = CallbackIdentifiers.ClientInventory + 0; public const int CallbackId = CallbackIdentifiers.ClientInventory + 0;
public int Andle; // m_handle SteamInventoryResult_t public int Handle; // m_handle SteamInventoryResult_t
public Result Esult; // m_result enum EResult public Result Esult; // m_result enum EResult
// //
@ -7247,7 +7250,7 @@ namespace SteamNative
[StructLayout( LayoutKind.Sequential, Pack = 4 )] [StructLayout( LayoutKind.Sequential, Pack = 4 )]
public struct PackSmall public struct PackSmall
{ {
public int Andle; // m_handle SteamInventoryResult_t public int Handle; // m_handle SteamInventoryResult_t
public Result Esult; // m_result enum EResult public Result Esult; // m_result enum EResult
// //
@ -7257,7 +7260,7 @@ namespace SteamNative
{ {
return new SteamInventoryResultReady_t() return new SteamInventoryResultReady_t()
{ {
Andle = d.Andle, Handle = d.Handle,
Esult = d.Esult, Esult = d.Esult,
}; };
} }
@ -7276,7 +7279,7 @@ namespace SteamNative
public struct SteamInventoryFullUpdate_t public struct SteamInventoryFullUpdate_t
{ {
public const int CallbackId = CallbackIdentifiers.ClientInventory + 1; public const int CallbackId = CallbackIdentifiers.ClientInventory + 1;
public int Andle; // m_handle SteamInventoryResult_t public int Handle; // m_handle SteamInventoryResult_t
// //
// Read this struct from a pointer, usually from Native // Read this struct from a pointer, usually from Native
@ -7289,7 +7292,7 @@ namespace SteamNative
[StructLayout( LayoutKind.Sequential, Pack = 4 )] [StructLayout( LayoutKind.Sequential, Pack = 4 )]
public struct PackSmall public struct PackSmall
{ {
public int Andle; // m_handle SteamInventoryResult_t public int Handle; // m_handle SteamInventoryResult_t
// //
// Easily convert from PackSmall to SteamInventoryFullUpdate_t // Easily convert from PackSmall to SteamInventoryFullUpdate_t
@ -7298,7 +7301,7 @@ namespace SteamNative
{ {
return new SteamInventoryFullUpdate_t() return new SteamInventoryFullUpdate_t()
{ {
Andle = d.Andle, Handle = d.Handle,
}; };
} }

View File

@ -41,7 +41,7 @@ namespace Generator
{ {
Console.WriteLine( t.Name ); Console.WriteLine( t.Name );
var r = new Regex( @"struct "+t.Name+@"\n{\n(?:.)+enum { k_iCallback = (.+) \+ ([0-9]+)", RegexOptions.Multiline | RegexOptions.IgnoreCase ); var r = new Regex( @"struct "+t.Name+@"\n{ ?\n(?:.)+enum { k_iCallback = (.+) \+ ([0-9]+)", RegexOptions.Multiline | RegexOptions.IgnoreCase );
var m = r.Match( Content ); var m = r.Match( Content );
if ( m.Success ) if ( m.Success )
{ {

View File

@ -35,6 +35,7 @@ namespace Generator
if ( m == "m_pubParam" ) return "ParamPtr"; if ( m == "m_pubParam" ) return "ParamPtr";
if ( m == "m_cubParam" ) return "ParamCount"; if ( m == "m_cubParam" ) return "ParamCount";
if ( m == "m_itemId" ) return "ItemId"; if ( m == "m_itemId" ) return "ItemId";
if ( m == "m_handle" ) return "Handle";
var cleanName = m.Replace( "m_un", "" ) var cleanName = m.Replace( "m_un", "" )
.Replace( "m_us", "" ) .Replace( "m_us", "" )