2023-05-01 20:06:46 +00:00
|
|
|
class YAS extends Info
|
|
|
|
config(YAS);
|
|
|
|
|
|
|
|
const LatestVersion = 1;
|
|
|
|
|
|
|
|
const CfgRanks = class'Ranks';
|
|
|
|
const CfgRankRelations = class'RankRelations';
|
|
|
|
const CfgMessageOfTheDay = class'MessageOfTheDay';
|
|
|
|
|
|
|
|
const UpdateInterval = 1.0f;
|
|
|
|
|
|
|
|
const MatchUID = "0x";
|
|
|
|
const MatchPlayerSteamID64 = "76561";
|
|
|
|
const MatchGroupSteamID64 = "10358279";
|
|
|
|
|
|
|
|
var private config int Version;
|
|
|
|
var private config E_LogLevel LogLevel;
|
|
|
|
|
|
|
|
var private KFGameInfo KFGI;
|
|
|
|
var private KFGameInfo_Survival KFGIS;
|
|
|
|
var private KFGameInfo_Endless KFGIE;
|
|
|
|
var private KFGameReplicationInfo KFGRI;
|
|
|
|
var private KFOnlineGameSettings KFOGS;
|
|
|
|
|
|
|
|
var private OnlineSubsystemSteamworks OSS;
|
|
|
|
|
|
|
|
var private Array<YAS_RepInfoOwner> RepInfos;
|
|
|
|
|
|
|
|
var private Array<CachedRankRelation> PlayerRelations;
|
|
|
|
var private Array<CachedRankRelation> GroupRelations;
|
|
|
|
|
|
|
|
var private int LastMessageID;
|
|
|
|
|
|
|
|
public simulated function bool SafeDestroy()
|
|
|
|
{
|
|
|
|
`Log_Trace();
|
|
|
|
|
|
|
|
return (bPendingDelete || bDeleteMe || Destroy());
|
|
|
|
}
|
|
|
|
|
|
|
|
public event PreBeginPlay()
|
|
|
|
{
|
|
|
|
`Log_Trace();
|
|
|
|
|
|
|
|
if (WorldInfo.NetMode == NM_Client)
|
|
|
|
{
|
|
|
|
`Log_Fatal("NetMode == NM_Client");
|
|
|
|
SafeDestroy();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Super.PreBeginPlay();
|
|
|
|
|
|
|
|
PreInit();
|
|
|
|
}
|
|
|
|
|
|
|
|
public event PostBeginPlay()
|
|
|
|
{
|
|
|
|
`Log_Trace();
|
|
|
|
|
|
|
|
if (bPendingDelete || bDeleteMe) return;
|
|
|
|
|
|
|
|
Super.PostBeginPlay();
|
|
|
|
|
|
|
|
PostInit();
|
|
|
|
}
|
|
|
|
|
|
|
|
private function PreInit()
|
|
|
|
{
|
|
|
|
`Log_Trace();
|
|
|
|
|
|
|
|
if (Version == `NO_CONFIG)
|
|
|
|
{
|
|
|
|
LogLevel = LL_Info;
|
|
|
|
SaveConfig();
|
|
|
|
}
|
|
|
|
|
|
|
|
CfgRanks.static.InitConfig(Version, LatestVersion);
|
|
|
|
CfgRankRelations.static.InitConfig(Version, LatestVersion);
|
|
|
|
CfgMessageOfTheDay.static.InitConfig(Version, LatestVersion);
|
|
|
|
|
|
|
|
switch (Version)
|
|
|
|
{
|
|
|
|
case `NO_CONFIG:
|
|
|
|
`Log_Info("Config created");
|
|
|
|
|
|
|
|
case MaxInt:
|
|
|
|
`Log_Info("Config updated to version" @ LatestVersion);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case LatestVersion:
|
|
|
|
`Log_Info("Config is up-to-date");
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
`Log_Warn("The config version is higher than the current version (are you using an old mutator?)");
|
|
|
|
`Log_Warn("Config version is" @ Version @ "but current version is" @ LatestVersion);
|
|
|
|
`Log_Warn("The config version will be changed to" @ LatestVersion);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (LatestVersion != Version)
|
|
|
|
{
|
|
|
|
Version = LatestVersion;
|
|
|
|
SaveConfig();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (LogLevel == LL_WrongLevel)
|
|
|
|
{
|
|
|
|
LogLevel = LL_Info;
|
|
|
|
`Log_Warn("Wrong 'LogLevel', return to default value");
|
|
|
|
SaveConfig();
|
|
|
|
}
|
|
|
|
`Log_Base("LogLevel:" @ LogLevel);
|
|
|
|
|
|
|
|
OSS = OnlineSubsystemSteamworks(class'GameEngine'.static.GetOnlineSubsystem());
|
|
|
|
if (OSS != None)
|
|
|
|
{
|
|
|
|
InitRanks();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
`Log_Error("Can't get online subsystem!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private function InitRanks()
|
|
|
|
{
|
|
|
|
local Array<RankRelation> Relations;
|
|
|
|
local RankRelation Relation;
|
|
|
|
|
|
|
|
Relations = CfgRankRelations.default.Relation;
|
|
|
|
|
|
|
|
foreach Relations(Relation)
|
|
|
|
{
|
|
|
|
if (IsUID(Relation.ObjectID) || IsPlayerSteamID64(Relation.ObjectID))
|
|
|
|
{
|
|
|
|
AddRelation(Relation, PlayerRelations);
|
|
|
|
}
|
|
|
|
else if (IsGroupSteamID64(Relation.ObjectID))
|
|
|
|
{
|
|
|
|
AddRelation(Relation, GroupRelations);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
`Log_Warn("Can't parse ID:" @ Relation.ObjectID);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private function AddRelation(RankRelation Relation, out Array<CachedRankRelation> OutArray)
|
|
|
|
{
|
|
|
|
local CachedRankRelation CachedRankRelation;
|
|
|
|
local Array<Rank> Ranks;
|
|
|
|
local Rank Rank;
|
|
|
|
|
|
|
|
if (AnyToUID(Relation.ObjectID, CachedRankRelation.UID))
|
|
|
|
{
|
|
|
|
CachedRankRelation.RawID = Relation.ObjectID;
|
|
|
|
|
|
|
|
Ranks = CfgRanks.default.Rank;
|
|
|
|
foreach Ranks(Rank)
|
|
|
|
{
|
|
|
|
if (Rank.RankID == Relation.RankID)
|
|
|
|
{
|
|
|
|
CachedRankRelation.Rank = Rank;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (CachedRankRelation.Rank.RankID > 0)
|
|
|
|
{
|
|
|
|
OutArray.AddItem(CachedRankRelation);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
`Log_Warn("Rank with ID" @ Relation.RankID @ "not found");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
`Log_Warn("Can't convert to UniqueNetID:" @ Relation.ObjectID);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static function bool IsUID(String ID)
|
|
|
|
{
|
|
|
|
return (Left(ID, Len(MatchUID)) ~= MatchUID);
|
|
|
|
}
|
|
|
|
|
|
|
|
private static function bool IsPlayerSteamID64(String ID)
|
|
|
|
{
|
|
|
|
return (Left(ID, Len(MatchPlayerSteamID64)) ~= MatchPlayerSteamID64);
|
|
|
|
}
|
|
|
|
|
|
|
|
private static function bool IsGroupSteamID64(String ID)
|
|
|
|
{
|
|
|
|
return (Left(ID, Len(MatchGroupSteamID64)) ~= MatchGroupSteamID64);
|
|
|
|
}
|
|
|
|
|
|
|
|
private function bool AnyToUID(String ID, out UniqueNetId UID)
|
|
|
|
{
|
|
|
|
return IsUID(ID) ? OSS.StringToUniqueNetId(ID, UID) : OSS.Int64ToUniqueNetId(ID, UID);
|
|
|
|
}
|
|
|
|
|
|
|
|
private function PostInit()
|
|
|
|
{
|
|
|
|
`Log_Trace();
|
|
|
|
|
|
|
|
if (WorldInfo == None || WorldInfo.Game == None)
|
|
|
|
{
|
|
|
|
SetTimer(1.0f, false, nameof(PostInit));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
KFGI = KFGameInfo(WorldInfo.Game);
|
|
|
|
if (KFGI == None || KFGameInfo_VersusSurvival(KFGI) != None) // VersusSurvival is not supported (yet)
|
|
|
|
{
|
|
|
|
`Log_Fatal("Incompatible gamemode:" @ WorldInfo.Game);
|
|
|
|
SafeDestroy();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
KFGI.HUDType = class'YAS_HUD';
|
|
|
|
|
|
|
|
if (KFGI.GameReplicationInfo == None)
|
|
|
|
{
|
|
|
|
SetTimer(1.0f, false, nameof(PostInit));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
KFGRI = KFGameReplicationInfo(KFGI.GameReplicationInfo);
|
|
|
|
if (KFGRI == None)
|
|
|
|
{
|
|
|
|
`Log_Fatal("Incompatible Replication info:" @ KFGI.GameReplicationInfo);
|
|
|
|
SafeDestroy();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (KFGI.PlayfabInter != None && KFGI.PlayfabInter.GetGameSettings() != None)
|
|
|
|
{
|
|
|
|
KFOGS = KFOnlineGameSettings(KFGI.PlayfabInter.GetGameSettings());
|
|
|
|
}
|
|
|
|
else if (KFGI.GameInterface != None)
|
|
|
|
{
|
|
|
|
KFOGS = KFOnlineGameSettings(
|
|
|
|
KFGI.GameInterface.GetGameSettings(
|
|
|
|
KFGI.PlayerReplicationInfoClass.default.SessionName));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (KFOGS == None)
|
|
|
|
{
|
|
|
|
SetTimer(1.0f, false, nameof(PostInit));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
KFGIS = KFGameInfo_Survival(KFGI);
|
|
|
|
KFGIE = KFGameInfo_Endless(KFGI);
|
|
|
|
|
|
|
|
SetTimer(UpdateInterval, true, nameof(UpdateTimer));
|
|
|
|
|
|
|
|
if (CfgMessageOfTheDay.default.Message.Length > 0)
|
|
|
|
{
|
|
|
|
MessageOfTheDayTimer();
|
|
|
|
SetTimer(CfgMessageOfTheDay.default.DisplayTime, true, nameof(MessageOfTheDayTimer));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private function UpdateTimer()
|
|
|
|
{
|
|
|
|
local YAS_RepInfoOwner RepInfo;
|
|
|
|
|
|
|
|
foreach RepInfos(RepInfo)
|
|
|
|
{
|
|
|
|
RepInfo.DynamicServerName = KFOGS.OwningPlayerName;
|
|
|
|
RepInfo.UsesStats = KFOGS.bUsesStats;
|
|
|
|
RepInfo.Custom = KFOGS.bCustom;
|
|
|
|
RepInfo.PasswordRequired = KFOGS.bRequiresPassword;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private function MessageOfTheDayTimer()
|
|
|
|
{
|
|
|
|
local YAS_RepInfoOwner RepInfo;
|
|
|
|
local int MessageIndex;
|
|
|
|
|
|
|
|
if (CfgMessageOfTheDay.default.bRandomize)
|
|
|
|
{
|
|
|
|
MessageIndex = Rand(CfgMessageOfTheDay.default.Message.Length);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
MessageIndex = LastMessageID + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (MessageIndex == LastMessageID)
|
|
|
|
{
|
|
|
|
++MessageIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (MessageIndex >= CfgMessageOfTheDay.default.Message.Length)
|
|
|
|
{
|
|
|
|
MessageIndex = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach RepInfos(RepInfo)
|
|
|
|
{
|
|
|
|
RepInfo.MessageOfTheDay = CfgMessageOfTheDay.default.Message[MessageIndex];
|
|
|
|
}
|
|
|
|
|
|
|
|
LastMessageID = MessageIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function NotifyLogin(Controller C)
|
|
|
|
{
|
|
|
|
local YAS_RepInfoOwner RepInfo;
|
|
|
|
|
|
|
|
`Log_Trace();
|
|
|
|
|
|
|
|
RepInfo = CreateRepInfo(C);
|
|
|
|
if (RepInfo == None)
|
|
|
|
{
|
|
|
|
`Log_Error("Can't create RepInfo for:" @ C);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
InitRank(RepInfo);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function NotifyLogout(Controller C)
|
|
|
|
{
|
|
|
|
local YAS_RepInfoOwner RepInfo;
|
|
|
|
|
|
|
|
`Log_Trace();
|
|
|
|
|
|
|
|
RepInfo = FindRepInfo(C);
|
|
|
|
|
|
|
|
if (!DestroyRepInfo(RepInfo))
|
|
|
|
{
|
|
|
|
`Log_Error("Can't destroy RepInfo of:" @ C);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function YAS_RepInfoOwner CreateRepInfo(Controller C)
|
|
|
|
{
|
|
|
|
local YAS_RepInfoOwner OwnerRepInfo;
|
|
|
|
local YAS_RepInfoPlayer PlayerRepInfo;
|
|
|
|
|
|
|
|
`Log_Trace();
|
|
|
|
|
|
|
|
OwnerRepInfo = Spawn(class'YAS_RepInfoOwner', C);
|
|
|
|
PlayerRepInfo = Spawn(class'YAS_RepInfoPlayer', C);
|
|
|
|
|
|
|
|
if (OwnerRepInfo != None && PlayerRepInfo != None)
|
|
|
|
{
|
|
|
|
RepInfos.AddItem(OwnerRepInfo);
|
|
|
|
|
2023-06-27 08:34:37 +00:00
|
|
|
PlayerRepInfo.Rank = class'YAS_Types'.static.FromSystemRank(CfgRanks.default.Player);
|
2023-05-01 20:06:46 +00:00
|
|
|
OwnerRepInfo.PlayerRepInfo = PlayerRepInfo;
|
|
|
|
OwnerRepInfo.YAS = Self;
|
|
|
|
OwnerRepInfo.LogLevel = LogLevel;
|
|
|
|
OwnerRepInfo.RankPlayer = CfgRanks.default.Player;
|
|
|
|
OwnerRepInfo.RankAdmin = CfgRanks.default.Admin;
|
|
|
|
OwnerRepInfo.MessageOfTheDay = CfgMessageOfTheDay.default.Message[LastMessageID];
|
|
|
|
|
|
|
|
return OwnerRepInfo;
|
|
|
|
}
|
|
|
|
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function YAS_RepInfoOwner FindRepInfo(Controller C)
|
|
|
|
{
|
|
|
|
local YAS_RepInfoOwner RepInfo;
|
|
|
|
|
|
|
|
if (C == None) return None;
|
|
|
|
|
|
|
|
foreach RepInfos(RepInfo)
|
|
|
|
{
|
|
|
|
if (RepInfo.Owner == C)
|
|
|
|
{
|
|
|
|
return RepInfo;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function bool DestroyRepInfo(YAS_RepInfoOwner RepInfo)
|
|
|
|
{
|
|
|
|
`Log_Trace();
|
|
|
|
|
|
|
|
if (RepInfo == None) return false;
|
|
|
|
|
|
|
|
RepInfos.RemoveItem(RepInfo);
|
|
|
|
RepInfo.PlayerRepInfo.SafeDestroy();
|
|
|
|
RepInfo.SafeDestroy();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function InitRank(YAS_RepInfoOwner RepInfo)
|
|
|
|
{
|
|
|
|
local CachedRankRelation Rel;
|
|
|
|
local String JoinedGroupIDs;
|
|
|
|
local PlayerReplicationInfo PRI;
|
|
|
|
local KFPlayerController KFPC;
|
|
|
|
local Array<String> StringGroupIDs;
|
|
|
|
|
|
|
|
`Log_Trace();
|
|
|
|
|
|
|
|
KFPC = RepInfo.GetKFPC();
|
|
|
|
|
|
|
|
if (KFPC == None) return;
|
|
|
|
|
|
|
|
PRI = KFPC.PlayerReplicationInfo;
|
|
|
|
if (PRI == None) return;
|
|
|
|
|
|
|
|
foreach PlayerRelations(Rel)
|
|
|
|
{
|
|
|
|
if (Rel.UID.Uid == PRI.UniqueID.Uid)
|
|
|
|
{
|
|
|
|
RepInfo.PlayerRepInfo.Rank = Rel.Rank;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (RepInfo.PlayerRepInfo.Rank.RankID <= 0 && !KFPC.bIsEosPlayer)
|
|
|
|
{
|
|
|
|
foreach GroupRelations(Rel)
|
|
|
|
{
|
|
|
|
StringGroupIDs.AddItem(Rel.RawID);
|
|
|
|
}
|
|
|
|
JoinArray(StringGroupIDs, JoinedGroupIDs);
|
|
|
|
RepInfo.CheckGroupRanks(JoinedGroupIDs);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function Rank RankByGroupID(UniqueNetId GroupUID)
|
|
|
|
{
|
|
|
|
local CachedRankRelation Rel;
|
|
|
|
|
|
|
|
foreach GroupRelations(Rel) if (Rel.UID == GroupUID) break;
|
|
|
|
|
|
|
|
return Rel.Rank;
|
|
|
|
}
|
|
|
|
|
|
|
|
DefaultProperties
|
|
|
|
{
|
|
|
|
|
2023-05-02 19:15:42 +00:00
|
|
|
}
|