// Written by .:..: (2009) Class ServerPerksMut extends Mutator Config(ServerPerks); struct ChatIconType { var() config string IconTexture,IconTag; var() config bool bCaseInsensitive; }; var() globalconfig array Perks,TraderInventory,WeaponCategories,CustomCharacters; var() globalconfig int MinPerksLevel,MaxPerksLevel,RemotePort,MidGameSaveWaves,FTPKeepAliveSec; var() globalconfig float RequirementScaling; var() globalconfig string RemoteDatabaseURL,RemotePassword,RemoteFTPUser,RemoteFTPDir,ServerNewsURL,FTPUploadAllIgnoreDate; var() globalconfig array SmileyTags; var array LoadedCategories; var array LoadInvCategory; var array< class > LoadPerks; var array< class > LoadInventory; var const int VersionNumber; var array PendingPlayers; var array ActiveStats; var localized string ServerPerksGroup; var transient InternetLink Link; var KFGameType KFGT; var int LastSavedWave,WaveCounter; var SRGameRules RulesMod; var transient array AddedServerPackages; var transient float NextCheckTimer; var array SmileyMsgs; var class SRScoreboardType,SRHudType,SRMenuType; var class SRControllerType; var() globalconfig bool bUploadAllStats,bForceGivePerk,bNoSavingProgress,bUseRemoteDatabase,bUsePlayerNameAsID,bMessageAnyPlayerLevelUp,bNoPerkChanges ,bUseLowestRequirements,bBWZEDTime,bUseEnhancedScoreboard,bOverrideUnusedCustomStats,bAllowAlwaysPerkChanges,bEnableWebAdmin ,bForceCustomChars,bEnableChatIcons,bEnhancedShoulderView,bFixGrenadeExploit,bAdminEditStats,bUseFTPLink,bDebugDatabase; var bool bEnabledEmoIcons; function PostBeginPlay() { local int i,j; local class V; local class P; local string S; local byte Cat; local class PR; local Texture T; local KFLevelRules R; if( RulesMod==None ) RulesMod = Spawn(Class'SRGameRules'); KFGT = KFGameType(Level.Game); if( Level.Game.HUDType~=Class'KFGameType'.Default.HUDType || Level.Game.HUDType~=Class'KFStoryGameInfo'.Default.HUDType ) { bEnabledEmoIcons = bEnableChatIcons; Level.Game.HUDType = string(SRHudType); } if( bUseEnhancedScoreboard && (Level.Game.ScoreBoardType~=Class'KFGameType'.Default.ScoreBoardType || Level.Game.ScoreBoardType~=Class'KFStoryGameInfo'.Default.ScoreBoardType) ) Level.Game.ScoreBoardType = string(SRScoreboardType); // Use own playercontroller class for security reasons. if( Level.Game.PlayerControllerClass==Class'KFPlayerController' || Level.Game.PlayerControllerClass==Class'KFPlayerController_Story' ) { Level.Game.PlayerControllerClass = SRControllerType; Level.Game.PlayerControllerClassName = string(SRControllerType); } DeathMatch(Level.Game).LoginMenuClass = string(SRMenuType); // Load perks. for( i=0; i(DynamicLoadObject(Perks[i],Class'Class')); if( V!=None ) { LoadPerks[LoadPerks.Length] = V; ImplementPackage(V); } } // Setup categories LoadedCategories.Length = WeaponCategories.Length; for( i=0; i0 ) { Cat = Min(int(Left(S,j)),LoadedCategories.Length-1); S = Mid(S,j+1); } else Cat = 0; P = class(DynamicLoadObject(S,Class'Class')); if( P!=None ) { // Inform bots. if( R!=None ) R.MediItemForSale[R.MediItemForSale.Length] = P; LoadInventory[LoadInventory.Length] = P; LoadInvCategory[LoadInvCategory.Length] = Cat; if( P.Outer.Name!='KFMod' ) ImplementPackage(P); } } // Load custom chars. for( i=0; i=0 ) S = Mid(S,j+1); PR = class(DynamicLoadObject(S$"Mod."$S,class'Class',true)); if( PR!=None ) { if( PR.Default.MeshName!="" ) // Add mesh package. ImplementPackage(DynamicLoadObject(PR.Default.MeshName,class'Mesh',true)); if( PR.Default.BodySkinName!="" ) // Add skin package. ImplementPackage(DynamicLoadObject(PR.Default.BodySkinName,class'Material',true)); ImplementPackage(PR); } } // Load chat icons if( bEnabledEmoIcons ) { j = 0; for( i=0; i V; local bool bAll; i = InStr(Cmd," "); if( i==-1 ) { Sender.ClientMessage("Usage: SetPerk "); return; } if( Left(Cmd,i)~="All" ) bAll = true; else ID = int(Left(Cmd,i)); Cmd = Mid(Cmd,i+1); for( i=0; i=0; --i ) if( AddedServerPackages[i]==O.Name ) return; AddedServerPackages[AddedServerPackages.Length] = O.Name; } function bool CheckReplacement(Actor Other, out byte bSuperRelevant) { if( PlayerController(Other)!=None ) { PendingPlayers[PendingPlayers.Length] = PlayerController(Other); SetTimer(0.1,false); } else if( Bot(Other)!=None && Bot(Other).PawnClass==Class'KFHumanPawn' ) { Bot(Other).PawnClass = Class'SRHumanPawn'; Bot(Other).PreviousPawnClass = Class'SRHumanPawn'; } else if( ServerStStats(Other)!=None ) SetServerPerks(ServerStStats(Other)); else if( ClientPerkRepLink(Other)!=None ) SetupRepLink(ClientPerkRepLink(Other)); return true; } function SetServerPerks( ServerStStats Stat ) { local int i; Stat.MutatorOwner = Self; Stat.Rep.ServerWebSite = ServerNewsURL; Stat.Rep.MinimumLevel = MinPerksLevel+1; Stat.Rep.MaximumLevel = MaxPerksLevel+1; Stat.Rep.RequirementScaling = RequirementScaling; Stat.Rep.CachePerks.Length = LoadPerks.Length; for( i=0; i=0; --i ) { if( KFPCServ(PendingPlayers[i])!=None ) KFPCServ(PendingPlayers[i]).bUseAdvBehindview = bEnhancedShoulderView; if( PendingPlayers[i]!=None && PendingPlayers[i].Player!=None && ServerStStats(PendingPlayers[i].SteamStatsAndAchievements)==None ) { if( PendingPlayers[i].SteamStatsAndAchievements!=None ) PendingPlayers[i].SteamStatsAndAchievements.Destroy(); PendingPlayers[i].SteamStatsAndAchievements = Spawn(Class'ServerStStats',PendingPlayers[i]); PendingPlayers[i].PlayerReplicationInfo.SteamStatsAndAchievements = PendingPlayers[i].SteamStatsAndAchievements; } } PendingPlayers.Length = 0; } final function string GetPlayerID( PlayerController PC ) { if( bUsePlayerNameAsID ) return PC.PlayerReplicationInfo.PlayerName; return PC.GetPlayerIDHash(); } function StatsObject GetStatsForPlayer( PlayerController PC ) { local StatsObject S; local string SId; local int i; if( Level.Game.bGameEnded ) return None; SId = GetPlayerID(PC); for( i=0; i=MidGameSaveWaves ) { WaveCounter = 0; SaveStats(); } } Auto state EndGameTracker { Begin: if( bUploadAllStats && Level.NetMode==NM_StandAlone ) { Sleep(1.f); FTPTcpLink(Link).FullUpload(); while( true ) { if( KFGT!=None ) KFGT.WaveCountDown = 60; Sleep(1.f); } } while( !Level.Game.bGameEnded ) { Sleep(1.f); if( MidGameSaveWaves>0 && KFGT!=None && KFGT.WaveNum!=LastSavedWave ) { LastSavedWave = KFGT.WaveNum; InitNextWave(); } if( Level.bLevelChange ) { SaveStats(); Stop; } } CheckWinOrLose(); SaveStats(); } static final function string GetSafeName( string S ) { S = Repl(S,"=","-"); S = Repl(S,Chr(10),""); // LF S = Repl(S,Chr(13),""); // CR S = Repl(S,"\"","'"); // " -> ' return S; } delegate SaveAllStats(); delegate RequestStats( ServerStStats Other ); static function FillPlayInfo(PlayInfo PlayInfo) { Super.FillPlayInfo(PlayInfo); PlayInfo.AddSetting(default.ServerPerksGroup,"MinPerksLevel","Min Perk Level",1,0, "Text", "4;-1:254"); PlayInfo.AddSetting(default.ServerPerksGroup,"MaxPerksLevel","Max Perk Level",1,0, "Text", "4;0:254"); PlayInfo.AddSetting(default.ServerPerksGroup,"RequirementScaling","Req Scaling",1,0, "Text", "6;0.01:4.00"); PlayInfo.AddSetting(default.ServerPerksGroup,"bForceGivePerk","Force perks",1,0, "Check"); PlayInfo.AddSetting(default.ServerPerksGroup,"bNoSavingProgress","No saving",1,0, "Check"); PlayInfo.AddSetting(default.ServerPerksGroup,"bAllowAlwaysPerkChanges","Unlimited perk changes",1,0, "Check"); PlayInfo.AddSetting(default.ServerPerksGroup,"bNoPerkChanges","No perk changes",1,0, "Check"); PlayInfo.AddSetting(default.ServerPerksGroup,"bUseRemoteDatabase","Use remote database",1,0, "Check"); PlayInfo.AddSetting(default.ServerPerksGroup,"bUseFTPLink","Use FTP remote database",1,0, "Check"); PlayInfo.AddSetting(default.ServerPerksGroup,"RemoteDatabaseURL","Remote database URL",1,1,"Text","64"); PlayInfo.AddSetting(default.ServerPerksGroup,"RemotePort","Remote database port",1,0, "Text", "5;0:65535"); PlayInfo.AddSetting(default.ServerPerksGroup,"RemotePassword","Remote database password",1,0, "Text", "64"); PlayInfo.AddSetting(default.ServerPerksGroup,"RemoteFTPUser","Remote database user",1,0, "Text", "64"); PlayInfo.AddSetting(default.ServerPerksGroup,"RemoteFTPDir","Remote database dir",1,0, "Text", "64"); PlayInfo.AddSetting(default.ServerPerksGroup,"FTPKeepAliveSec","FTP Keep alive sec",1,0, "Text", "6;0:600"); PlayInfo.AddSetting(default.ServerPerksGroup,"MidGameSaveWaves","MidGame Save Waves",1,0, "Text", "5;0:10"); PlayInfo.AddSetting(default.ServerPerksGroup,"ServerNewsURL","Newspage URL",1,0, "Text", "64"); PlayInfo.AddSetting(default.ServerPerksGroup,"bUsePlayerNameAsID","Use PlayerName as ID",1,0, "Check"); PlayInfo.AddSetting(default.ServerPerksGroup,"bMessageAnyPlayerLevelUp","Notify any levelup",1,0, "Check"); PlayInfo.AddSetting(default.ServerPerksGroup,"bUseLowestRequirements","Use lowest req",1,0, "Check"); PlayInfo.AddSetting(default.ServerPerksGroup,"bBWZEDTime","BW ZED-time",1,0, "Check"); PlayInfo.AddSetting(default.ServerPerksGroup,"bUseEnhancedScoreboard","Enhanced scoreboard",1,0, "Check"); PlayInfo.AddSetting(default.ServerPerksGroup,"bForceCustomChars","Force Custom Chars",1,0, "Check"); PlayInfo.AddSetting(default.ServerPerksGroup,"bEnableChatIcons","Enable chat icons",1,0, "Check"); PlayInfo.AddSetting(default.ServerPerksGroup,"bEnhancedShoulderView","Shoulder view",1,0, "Check"); PlayInfo.AddSetting(default.ServerPerksGroup,"bFixGrenadeExploit","No Grenade Exploit",1,0, "Check"); PlayInfo.AddSetting(default.ServerPerksGroup,"bAdminEditStats","Admin edit stats",1,0, "Check"); PlayInfo.AddSetting(default.ServerPerksGroup,"bEnableWebAdmin","SP WebAdmin",1,0, "Check"); } static event string GetDescriptionText(string PropName) { switch (PropName) { case "MinPerksLevel": return "Minimum perk level players can have."; case "MaxPerksLevel": return "Maximum perk level players can have."; case "RequirementScaling": return "Perk requirements scaling."; case "bForceGivePerk": return "Force all players to get at least a random perk if they have none selected."; case "bNoSavingProgress": return "Server shouldn't save perk progression."; case "bUseRemoteDatabase": return "Instead of storing perk data locally on server, use remote data storeage server."; case "bUseFTPLink": return "Use FTP transmission for remote database."; case "RemoteDatabaseURL": return "URL of the remote database."; case "RemotePort": return "Port of the remote database."; case "RemotePassword": return "Password for server to access the remote database."; case "RemoteFTPUser": return "User name for server to access the remote database (only for FTP mode)."; case "MidGameSaveWaves": return "Between how many waves should it mid-game save stats."; case "bUsePlayerNameAsID": return "Use PlayerName's as ID instead of ID Hash."; case "bMessageAnyPlayerLevelUp": return "Broadcast a global message anytime someone gains a perk upgrade."; case "bUseLowestRequirements": return "Use lowest form of requirements for perks."; case "bBWZEDTime": return "Make screen go black and white during ZED-time."; case "bUseEnhancedScoreboard": return "Should use serverperk's own scoreboard."; case "bAllowAlwaysPerkChanges": return "Allow unlimited perk changes."; case "bForceCustomChars": return "Force players to use specified custom characters."; case "bEnableChatIcons": return "Should enable chat icons to replace specific tags in chat."; case "bEnhancedShoulderView": return "Should enable a more enhanced on shoulder behindview."; case "bFixGrenadeExploit": return "Should fix unlimited grenades glitch/exploit."; case "bAdminEditStats": return "Allow admins edit stats through an admin menu."; case "ServerNewsURL": return "Server newspage menu URL for page contents."; case "RemoteFTPDir": return "Remote FTP database data storage directory."; case "FTPKeepAliveSec": return "Keep FTP database connection alive with this many sec interval."; case "bEnableWebAdmin": return "Enable additional webserver interface."; case "bNoPerkChanges": return "Never allow players change perk during match."; } return Super.GetDescriptionText(PropName); } defaultproperties { Perks(0)="ServerPerksP.SRVetSupportSpec" Perks(1)="ServerPerksP.SRVetBerserker" Perks(2)="ServerPerksP.SRVetCommando" Perks(3)="ServerPerksP.SRVetFieldMedic" Perks(4)="ServerPerksP.SRVetFirebug" Perks(5)="ServerPerksP.SRVetSharpshooter" Perks(6)="ServerPerksP.SRVetDemolitions" TraderInventory(0)="5:KFMod.MP7MPickup" TraderInventory(1)="5:KFMod.BlowerThrowerPickup" TraderInventory(2)="5:KFMod.MP5MPickup" TraderInventory(3)="5:KFMod.M7A3MPickup" TraderInventory(4)="5:KFMod.KrissMPickup" TraderInventory(5)="2:KFMod.ShotgunPickup" TraderInventory(6)="2:KFMod.KSGPickup" TraderInventory(7)="2:KFMod.BoomStickPickup" TraderInventory(8)="2:KFMod.BenelliPickup" TraderInventory(9)="2:KFMod.AA12Pickup" TraderInventory(10)="2:KFMod.NailGunPickup" TraderInventory(11)="2:KFMod.SPShotGunPickup" TraderInventory(12)="1:KFMod.DualiesPickup" TraderInventory(13)="1:KFMod.MK23Pickup" TraderInventory(14)="1:KFMod.DualMK23Pickup" TraderInventory(15)="1:KFMod.Magnum44Pickup" TraderInventory(16)="1:KFMod.Dual44MagnumPickup" TraderInventory(17)="1:KFMod.DeaglePickup" TraderInventory(18)="1:KFMod.DualDeaglePickup" TraderInventory(19)="3:KFMod.WinchesterPickup" TraderInventory(20)="3:KFMod.CrossbowPickup" TraderInventory(21)="3:KFMod.M14EBRPickup" TraderInventory(22)="3:KFMod.M99Pickup" TraderInventory(23)="3:KFMod.SPSniperPickup" TraderInventory(24)="4:KFMod.BullpupPickup" TraderInventory(25)="4:KFMod.AK47Pickup" TraderInventory(26)="4:KFMod.MKb42Pickup" TraderInventory(27)="4:KFMod.M4Pickup" TraderInventory(28)="4:KFMod.SCARMK17Pickup" TraderInventory(29)="4:KFMod.FNFAL_ACOG_Pickup" TraderInventory(30)="4:KFMod.ThompsonPickup" TraderInventory(31)="4:KFMod.SPThompsonPickup" TraderInventory(32)="4:KFMod.ThompsonDrumPickup" TraderInventory(33)="0:KFMod.MachetePickup" TraderInventory(34)="0:KFMod.AxePickup" TraderInventory(35)="0:KFMod.ChainsawPickup" TraderInventory(36)="0:KFMod.KatanaPickup" TraderInventory(37)="0:KFMod.ClaymoreSwordPickup" TraderInventory(38)="0:KFMod.CrossbuzzsawPickup" TraderInventory(39)="0:KFMod.ScythePickup" TraderInventory(40)="0:KFMod.DwarfAxePickup" TraderInventory(41)="7:KFMod.FlameThrowerPickup" TraderInventory(42)="2:KFMod.TrenchgunPickup" TraderInventory(43)="1:KFMod.FlareRevolverPickup" TraderInventory(44)="1:KFMod.DualFlareRevolverPickup" TraderInventory(45)="4:KFMod.MAC10Pickup" TraderInventory(46)="7:KFMod.HuskGunPickup" TraderInventory(47)="6:KFMod.PipeBombPickup" TraderInventory(48)="6:KFMod.M79Pickup" TraderInventory(49)="6:KFMod.M32Pickup" TraderInventory(50)="4:KFMod.M4203Pickup" TraderInventory(51)="6:KFMod.SPGrenadePickup" TraderInventory(52)="6:KFMod.LAWPickup" TraderInventory(53)="6:KFMod.SealSquealPickup" TraderInventory(54)="6:KFMod.SeekerSixPickup" TraderInventory(55)="8:KFMod.ZEDGunPickup" TraderInventory(56)="8:KFMod.ZEDMKIIPickup" TraderInventory(57)="2:KFMod.GoldenAA12Pickup" TraderInventory(58)="4:KFMod.GoldenAK47Pickup" TraderInventory(59)="2:KFMod.GoldenBenelliPickup" TraderInventory(60)="0:KFMod.GoldenChainsawPickup" TraderInventory(61)="1:KFMod.GoldenDeaglePickup" TraderInventory(62)="1:KFMod.GoldenDualDeaglePickup" TraderInventory(63)="7:KFMod.GoldenFTPickup" TraderInventory(64)="0:KFMod.GoldenKatanaPickup" TraderInventory(65)="6:KFMod.GoldenM79Pickup" TraderInventory(66)="4:KFMod.CamoMP5MPickup" TraderInventory(67)="2:KFMod.CamoShotgunPickup" TraderInventory(68)="4:KFMod.CamoM4Pickup" TraderInventory(69)="6:KFMod.CamoM32Pickup" TraderInventory(70)="4:KFMod.NeonAK47Pickup" TraderInventory(71)="5:KFMod.NeonKrissMPickup" TraderInventory(72)="2:KFMod.NeonKSGPickup" TraderInventory(73)="4:KFMod.NeonSCARMK17Pickup" WeaponCategories(0)="4:Melee" WeaponCategories(1)="2:Pistol" WeaponCategories(2)="1:Shotgun" WeaponCategories(3)="2:Sniper" WeaponCategories(4)="3:Machine Gun" WeaponCategories(5)="0:Medic Gun" WeaponCategories(6)="6:Explosive" WeaponCategories(7)="5:Flame Thrower" WeaponCategories(8)="7:Misc" MaxPerksLevel=6 RemotePort=5000 RequirementScaling=1.000000 RemoteDatabaseURL="192.168.1.33" RemotePassword="Pass" RemoteFTPUser="User" SmileyTags(0)=(iconTexture="ServerPerks.I_Mad",IconTag=">:(") SmileyTags(1)=(iconTexture="ServerPerks.I_Frown",IconTag=":(") SmileyTags(2)=(iconTexture="ServerPerks.I_GreenLickB",IconTag=":)") SmileyTags(3)=(iconTexture="ServerPerks.I_Tongue",IconTag=":P",bCaseInsensitive=True) SmileyTags(4)=(iconTexture="ServerPerks.I_GreenLick",IconTag=":d") SmileyTags(5)=(iconTexture="ServerPerks.I_BigGrin",IconTag=":D") SmileyTags(6)=(iconTexture="ServerPerks.I_Indiffe",IconTag=":|") SmileyTags(7)=(iconTexture="ServerPerks.I_Ohwell",IconTag=":/") SmileyTags(8)=(iconTexture="ServerPerks.I_RedFace",IconTag=":*") SmileyTags(9)=(iconTexture="ServerPerks.I_RedFace",IconTag=":-*") SmileyTags(10)=(iconTexture="ServerPerks.I_Ban",IconTag="Ban?",bCaseInsensitive=True) SmileyTags(11)=(iconTexture="ServerPerks.I_Cool",IconTag="B)") SmileyTags(12)=(iconTexture="ServerPerks.I_Hmm",IconTag="Hmm") SmileyTags(13)=(iconTexture="ServerPerks.I_Scream",IconTag="XD") SmileyTags(14)=(iconTexture="ServerPerks.I_Spam",IconTag="SPAM") VersionNumber=750 ServerPerksGroup="Server Perks" SRScoreboardType=Class'ServerPerks.SRScoreBoard' SRHudType=Class'ServerPerks.SRHUDKillingFloor' SRMenuType=Class'ServerPerks.SRInvasionLoginMenu' SRControllerType=Class'ServerPerks.KFPCServ' bUseEnhancedScoreboard=True bEnableWebAdmin=True bEnableChatIcons=True bEnhancedShoulderView=True bFixGrenadeExploit=True bAdminEditStats=True GroupName="KF-Stats" FriendlyName="Server Veterancy Handler V7" Description="Use perks as privately on this server config instead of getting from global steam stats." }