mirror of
https://github.com/Deathgarden-Rebirth/Deathgarden_Rebirth-Rewrite.git
synced 2026-03-21 18:04:46 -05:00
Merge pull request #60 from Deathgarden-Rebirth/feature-filemanager_history
Feature file manager history
This commit is contained in:
commit
45fa0f2483
|
|
@ -40,36 +40,55 @@ abstract class CharacterItemConfig
|
|||
|
||||
protected static array $additionalPowers = [];
|
||||
|
||||
public static function getCharacterId(): UuidInterface {
|
||||
public static function getCharacterId(): UuidInterface
|
||||
{
|
||||
return Uuid::fromHexadecimal(new Hexadecimal(static::$characterId));
|
||||
}
|
||||
|
||||
public static function getDefaultEquippedPerks(): array {
|
||||
public static function getDefaultEquippedPerks(): array
|
||||
{
|
||||
return static::$defaultEquippedPerks;
|
||||
}
|
||||
|
||||
public static function getDefaultEquippedWeapons(): array {
|
||||
return static::$defaultEquippedWeapons;
|
||||
public static function getDefaultEquippedWeapons(): array
|
||||
{
|
||||
return [
|
||||
...static::$defaultEquippedWeapons,
|
||||
];
|
||||
}
|
||||
|
||||
public static function getDefaultEquipment(): array {
|
||||
public static function getDefaultEquipment(): array
|
||||
{
|
||||
return static::$defaultEquipment;
|
||||
}
|
||||
|
||||
public static function getDefaultEquippedBonuses(): array {
|
||||
public static function getDefaultEquippedBonuses(): array
|
||||
{
|
||||
return static::$defaultEquippedBonuses;
|
||||
}
|
||||
|
||||
public static function getDefaultPowers()
|
||||
public static function getDefaultPowers(): array
|
||||
{
|
||||
return static::$defaultEquippedPowers;
|
||||
return [
|
||||
...static::$defaultEquippedPowers,
|
||||
...static::$additionalPowers,
|
||||
];
|
||||
}
|
||||
|
||||
public static function getAllowedPerks(): array {
|
||||
public static function getDefaultWeapons(): array {
|
||||
return [
|
||||
...static::$defaultEquippedWeapons,
|
||||
...static::$additionalWeapons,
|
||||
];
|
||||
}
|
||||
|
||||
public static function getAllowedPerks(): array
|
||||
{
|
||||
return [...static::$additionalPerks, ...static::$defaultEquippedPerks];
|
||||
}
|
||||
|
||||
public static function getAllowedWeapons(): array {
|
||||
public static function getAllowedWeapons(): array
|
||||
{
|
||||
return [...static::$additionalWeapons, ...static::$defaultEquippedWeapons];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ class InquisitorItemConfig extends CharacterItemConfig
|
|||
];
|
||||
|
||||
protected static array $defaultEquippedWeapons = [
|
||||
'50D3005B437066E4C4D99F9397CF1B0B',
|
||||
'48072EAA49C83C6F387236955B3C7B6E',
|
||||
'46B5D90B466F5CB8D13035BEEB11774D',
|
||||
'5925AB494B3E90DD520E6B8A418B4AEF',
|
||||
];
|
||||
|
||||
protected static array $defaultEquipment = [
|
||||
|
|
@ -102,36 +102,36 @@ class InquisitorItemConfig extends CharacterItemConfig
|
|||
];
|
||||
|
||||
protected static array $additionalWeapons = [
|
||||
'0A9DB5BC418E1EE3F256D59129BB4E5B',
|
||||
'2BBB9DD842102F0818864F83FDDE8577',
|
||||
'D2BF15FC4BC92D230DF5DD983DFC2ED4',
|
||||
'D9F4022445A9905B8D37429F870F911E',
|
||||
'BCB675974E4757CA9CD2ACB80AAD4881',
|
||||
'1808EF1C4A86E2E984522D9763791771',
|
||||
'877F8AE8438318FC69F238950D41FFB7',
|
||||
'5691AC1B43E8AC7606D59BACC213FDB1',
|
||||
'472DB7284944C0E569411DBB33C07107',
|
||||
'792590BE451B239CC0E6838C3B2E0C11',
|
||||
'3540E3DC4010A6EE61C1CE8002EE4633',
|
||||
'973C9176404A29F926D13BACB76A2425',
|
||||
'46B5D90B466F5CB8D13035BEEB11774D',
|
||||
'50D3005B437066E4C4D99F9397CF1B0B',
|
||||
'682EC6AF444E8B15035489B7B59D7026',
|
||||
'C84FCD1A4E518AC0C520A89F25870D83',
|
||||
'91E4726C472DAAD995C0EB8E7ADB28CD',
|
||||
'80A2BF864A6E743B95D8A8BBA20E286E',
|
||||
'80B0BA974566289F2819AA85B5F50969',
|
||||
'91E4726C472DAAD995C0EB8E7ADB28CD',
|
||||
'C84FCD1A4E518AC0C520A89F25870D83',
|
||||
'0A9DB5BC418E1EE3F256D59129BB4E5B',
|
||||
'EFC6A5BE442C2554DB9D84AC5F2F0F5C',
|
||||
'1054BCA742B538D9EF7C5482B6A94B51',
|
||||
'48072EAA49C83C6F387236955B3C7B6E',
|
||||
'4F5758F14D7404EB36CEB79D1917F35A',
|
||||
'557039DA4846C1D85F63E98BE618E1BE',
|
||||
'682EC6AF444E8B15035489B7B59D7026',
|
||||
'2BBB9DD842102F0818864F83FDDE8577',
|
||||
'50D3005B437066E4C4D99F9397CF1B0B',
|
||||
'5925AB494B3E90DD520E6B8A418B4AEF',
|
||||
'5CBB9D9740F8A4B0CF8A63AF7F336C8F',
|
||||
'645074744007206132D20DAD7BE60D60',
|
||||
'CE9B843E414FBE382247C48F935CC5FA',
|
||||
'D40B955E444987490620FE978FC8DB07',
|
||||
'E949314146FBD7739DACF2AB17F2A8E2',
|
||||
'1E9F4B0B411B0CFF9009638EFBBB68BB',
|
||||
'31E332854F033E7370DB219F194871FA',
|
||||
'42029CB64E6D0E28CF818ABF164C7DE4',
|
||||
'4D4481224066F26EB62F08957BAAB7F8',
|
||||
'7A70DC4F40A5BC51F3944CAADE0D434B',
|
||||
'B83A141A45FB8D96D48A5185CD607AA3',
|
||||
'E4B6A31141FB3AF9271E18882CFC0DB6',
|
||||
'EC7BE7FF44840117459D8FBE2AE5BE27',
|
||||
'F8240052491F02CD1F1B73854173F0EB',
|
||||
'FB23E04C4730F3451388DF8CD2FAF31A',
|
||||
'D40B955E444987490620FE978FC8DB07',
|
||||
'557039DA4846C1D85F63E98BE618E1BE',
|
||||
'5CBB9D9740F8A4B0CF8A63AF7F336C8F',
|
||||
'4F5758F14D7404EB36CEB79D1917F35A',
|
||||
'1054BCA742B538D9EF7C5482B6A94B51',
|
||||
'CE9B843E414FBE382247C48F935CC5FA',
|
||||
'48072EAA49C83C6F387236955B3C7B6E',
|
||||
];
|
||||
|
||||
protected static array $additionalPowers = [
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class PoacherItemConfig extends CharacterItemConfig
|
|||
];
|
||||
|
||||
protected static array $defaultEquippedBonuses = [
|
||||
'4431395744543533907B099952F81510',
|
||||
'0FBE5C46F94E906875E84BA3C115B9B5',
|
||||
'6BE28177483A89CF00B2FD839726ACE1',
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@ class StalkerItemConfig extends CharacterItemConfig
|
|||
];
|
||||
|
||||
protected static array $defaultEquippedBonuses = [
|
||||
'791F12E047DA9E26E246E3859C3F587E',
|
||||
'8A5BF2274640C2F23EF3C996A6F6404D',
|
||||
'545F88D24EAD402513C4948DE31DD6AE',
|
||||
];
|
||||
|
||||
protected static array $defaultEquippedPowers = [
|
||||
|
|
@ -102,36 +102,36 @@ class StalkerItemConfig extends CharacterItemConfig
|
|||
];
|
||||
|
||||
protected static array $additionalWeapons = [
|
||||
'065629E04A181ADD3062169AAFB88F43',
|
||||
'0D96281E4440DF505B9CA8B1457F50D8',
|
||||
'1727C5E74C3C7454A6CC0FB1F7562CE2',
|
||||
'AB2F540D448B533998EC38B8ABAFFD35',
|
||||
'1BB15A214C78FBC23E74369682117834',
|
||||
'2C03CA70439065116446DA9F6F347900',
|
||||
'364665404243311408F6A0BD4DCE05BD',
|
||||
'858747E74B7F30A0F6C77888D2D255AF',
|
||||
'8CE61C214F9BD049028EF2B896D3B161',
|
||||
'912C2B42486993E01D0B9DB6F1D1E408',
|
||||
'AB2F540D448B533998EC38B8ABAFFD35',
|
||||
'192EC9DD4F40FE3C66F8A2AD84568769',
|
||||
'1945D4B24A31EB6C6CA508A4CDFBB44F',
|
||||
'1B51D59C47F565A20E743BA187B83642',
|
||||
'71F194C145E9629058957E9183C5C9C6',
|
||||
'773C61C84B175DB0314B809DC142739A',
|
||||
'7FD66FCD42766C53D2CB42A7A611B88E',
|
||||
'86711D8347A60ED764BE78A051CD4C11',
|
||||
'9AA46980454C38B8CBC1CE87F7E04F37',
|
||||
'CA7D61574EB6F0AE1D6D39A4EDD719D7',
|
||||
'D4CBB3C9425AB53EB481558BED82AE7C',
|
||||
'0FDFC87D45DF769282EA1FA7AB57E409',
|
||||
'8CE61C214F9BD049028EF2B896D3B161',
|
||||
'858747E74B7F30A0F6C77888D2D255AF',
|
||||
'0D96281E4440DF505B9CA8B1457F50D8',
|
||||
'065629E04A181ADD3062169AAFB88F43',
|
||||
'1727C5E74C3C7454A6CC0FB1F7562CE2',
|
||||
'364665404243311408F6A0BD4DCE05BD',
|
||||
'169446014AA2A782E51ECFAF9EF33A39',
|
||||
'307A0B13417737DED675309F8B978AB8',
|
||||
'3D535D304B5E5113CA31D2838C840129',
|
||||
'4E4E95BB4EBD26E7CFA0E489979DA0CC',
|
||||
'5DE495E742FB3EB0FBEF92BDE718E59F',
|
||||
'656CB0C644C6677C470D21AD0EA8437A',
|
||||
'8C365CF442AE795157A187B017E4D17F',
|
||||
'A9349C774A13D353C0F315BB7B979324',
|
||||
'C55D9EFF46EB08ABDD8467BC23969E53',
|
||||
'656CB0C644C6677C470D21AD0EA8437A',
|
||||
'3D535D304B5E5113CA31D2838C840129',
|
||||
'0FDFC87D45DF769282EA1FA7AB57E409',
|
||||
'307A0B13417737DED675309F8B978AB8',
|
||||
'773C61C84B175DB0314B809DC142739A',
|
||||
'9AA46980454C38B8CBC1CE87F7E04F37',
|
||||
'71F194C145E9629058957E9183C5C9C6',
|
||||
'7FD66FCD42766C53D2CB42A7A611B88E',
|
||||
'D4CBB3C9425AB53EB481558BED82AE7C',
|
||||
'CA7D61574EB6F0AE1D6D39A4EDD719D7',
|
||||
'192EC9DD4F40FE3C66F8A2AD84568769',
|
||||
'86711D8347A60ED764BE78A051CD4C11',
|
||||
'1945D4B24A31EB6C6CA508A4CDFBB44F',
|
||||
'1B51D59C47F565A20E743BA187B83642',
|
||||
];
|
||||
|
||||
protected static array $additionalPowers = [
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@ class VeteranItemConfig extends CharacterItemConfig
|
|||
];
|
||||
|
||||
protected static array $defaultEquippedBonuses = [
|
||||
'172080544A05F838E2473790FDF4873A',
|
||||
'3D377249421D35F0F750578919A7E210',
|
||||
'791F12E047DA9E26E246E3859C3F587E',
|
||||
'03783FB54D88B7D88DD4509FCBBAFE68',
|
||||
];
|
||||
|
||||
protected static array $defaultEquippedPowers = [
|
||||
|
|
@ -102,36 +102,37 @@ class VeteranItemConfig extends CharacterItemConfig
|
|||
];
|
||||
|
||||
protected static array $additionalWeapons = [
|
||||
'479BE509436547C4222CF6BB01802009',
|
||||
'6562B26B48C9C791C82A3EAE344EBEE1',
|
||||
'6F3359C54870B7B8A4D7B9A8C561D001',
|
||||
'90F742AD4BDE1CBF81B4B0BE57271C9B',
|
||||
'A17BA09141027848493CAA9D5EDC9D72',
|
||||
'A87672CA4D2BBFF35E273C82F2524278',
|
||||
'B02BE54A4758C5169593BC9EFF9DA028',
|
||||
'BBA2090F49BA1F26443400AC8ABD6A7D',
|
||||
'EC7BE7FF44840117459D8FBE2AE5BE27',
|
||||
'4D4481224066F26EB62F08957BAAB7F8',
|
||||
'1E9F4B0B411B0CFF9009638EFBBB68BB',
|
||||
'31E332854F033E7370DB219F194871FA',
|
||||
'7A70DC4F40A5BC51F3944CAADE0D434B',
|
||||
'42029CB64E6D0E28CF818ABF164C7DE4',
|
||||
'FB23E04C4730F3451388DF8CD2FAF31A',
|
||||
'F8240052491F02CD1F1B73854173F0EB',
|
||||
'E4B6A31141FB3AF9271E18882CFC0DB6',
|
||||
'B83A141A45FB8D96D48A5185CD607AA3',
|
||||
'EAF5179F4F62DCC06CE3E29F4E86207E',
|
||||
'479BE509436547C4222CF6BB01802009',
|
||||
'F317A5504A82074040F104A0AE68B360',
|
||||
'0606F8464D4C7EB70601CC84C50BCAC6',
|
||||
'22C48CEE49DC29EED48A82A7423DCCE6',
|
||||
'A17BA09141027848493CAA9D5EDC9D72',
|
||||
'6F3359C54870B7B8A4D7B9A8C561D001',
|
||||
'BBA2090F49BA1F26443400AC8ABD6A7D',
|
||||
'B02BE54A4758C5169593BC9EFF9DA028',
|
||||
'A87672CA4D2BBFF35E273C82F2524278',
|
||||
'90F742AD4BDE1CBF81B4B0BE57271C9B',
|
||||
'6562B26B48C9C791C82A3EAE344EBEE1',
|
||||
'23C4DCE74DB1D6CDC9147587F5C42450',
|
||||
'369D5D0C4175FD4445EF67BEF060B270',
|
||||
'377368444AFD0D25687CEBA2B721CEA9',
|
||||
'4BCE89A640F8687625ABF58B35A734AC',
|
||||
'4D3110C745832FC4FAD3CDBB2988CDD3',
|
||||
'D33211F643BF66DE32E555928266B97A',
|
||||
'EC2B43B6444929A1346A12B64D4DC8D3',
|
||||
'369D5D0C4175FD4445EF67BEF060B270',
|
||||
'D33211F643BF66DE32E555928266B97A',
|
||||
'4D3110C745832FC4FAD3CDBB2988CDD3',
|
||||
'4BCE89A640F8687625ABF58B35A734AC',
|
||||
'377368444AFD0D25687CEBA2B721CEA9',
|
||||
'FF5ADA454579CD95C8536DB944C75F24',
|
||||
'1808EF1C4A86E2E984522D9763791771',
|
||||
'3540E3DC4010A6EE61C1CE8002EE4633',
|
||||
'472DB7284944C0E569411DBB33C07107',
|
||||
'5691AC1B43E8AC7606D59BACC213FDB1',
|
||||
'792590BE451B239CC0E6838C3B2E0C11',
|
||||
'877F8AE8438318FC69F238950D41FFB7',
|
||||
'973C9176404A29F926D13BACB76A2425',
|
||||
'BCB675974E4757CA9CD2ACB80AAD4881',
|
||||
'D2BF15FC4BC92D230DF5DD983DFC2ED4',
|
||||
'D9F4022445A9905B8D37429F870F911E',
|
||||
'22C48CEE49DC29EED48A82A7423DCCE6',
|
||||
'0606F8464D4C7EB70601CC84C50BCAC6',
|
||||
|
||||
];
|
||||
|
||||
protected static array $additionalPowers = [
|
||||
|
|
|
|||
|
|
@ -94,26 +94,26 @@ class DashItemConfig extends CharacterItemConfig
|
|||
];
|
||||
|
||||
protected static array $additionalWeapons = [
|
||||
'097521AE4B974026F31B92BBAD436A38',
|
||||
'2331ED814F30635500FEDB96A0674A3A',
|
||||
'272369C042147225E364CFA42947859F',
|
||||
'36B2650B4564CC7E7ED310AD3FCA0D75',
|
||||
'66DAA6C946CA0A7C36314A94164B78BF',
|
||||
'98BCBE234BF7CCB50DC4A78CA78F8672',
|
||||
'9B6943CD4DF6CD2FCD94CB89E6F55380',
|
||||
'097521AE4B974026F31B92BBAD436A38',
|
||||
'36B2650B4564CC7E7ED310AD3FCA0D75',
|
||||
'A3FF5F7B4D2657164847319A2E52A0FD',
|
||||
'BE76A25F44710E8AD011B2B74ED3F3A9',
|
||||
'98BCBE234BF7CCB50DC4A78CA78F8672',
|
||||
'D93A7E864CFECE74FDE2D9BA50AB7135',
|
||||
'5A2DD3F6433AB83A725513B868D240CF',
|
||||
'240BC7484AF781EBA93C47932DA8D061',
|
||||
'2920B01748AA9AB4EC6299AD15FF0E6A',
|
||||
'3636FD2240F282F0921FA68E8F88ABBF',
|
||||
'2331ED814F30635500FEDB96A0674A3A',
|
||||
'9B6943CD4DF6CD2FCD94CB89E6F55380',
|
||||
'BE76A25F44710E8AD011B2B74ED3F3A9',
|
||||
'272369C042147225E364CFA42947859F',
|
||||
'BC8866F343E7970E145C889D9CE7B994',
|
||||
'42795DDF4ED4B7700A6555B586C5AD2B',
|
||||
'51C1825B4469FF483278DDB12D116E04',
|
||||
'8B886664468A2878B26813A097F375E5',
|
||||
'240BC7484AF781EBA93C47932DA8D061',
|
||||
'B2ECD91349955E809A54DB9B36B7D6CF',
|
||||
'BC8866F343E7970E145C889D9CE7B994',
|
||||
'DC91C3414F22F217BCB30590FAB59A9E',
|
||||
'8B886664468A2878B26813A097F375E5',
|
||||
'2920B01748AA9AB4EC6299AD15FF0E6A',
|
||||
'3636FD2240F282F0921FA68E8F88ABBF',
|
||||
'5A2DD3F6433AB83A725513B868D240CF',
|
||||
];
|
||||
|
||||
protected static array $defaultEquippedPowers = [
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ class FogItemConfig extends CharacterItemConfig
|
|||
|
||||
protected static array $defaultEquippedBonuses = [
|
||||
'1E08AFFA485E92BAFF2C1BB85CEFB81E',
|
||||
'1F5CD9004224C56746D81991AA40448A',
|
||||
'D8305B60C8455B51368681BFD337525A',
|
||||
];
|
||||
|
||||
protected static array $additionalPerks = [
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ class InkedItemConfig extends CharacterItemConfig
|
|||
];
|
||||
|
||||
protected static array $defaultEquippedBonuses = [
|
||||
'261144CC43A9F74A60506AB0335B23B2',
|
||||
'92B767F442A89C87CC3C9CB5D279D6EA',
|
||||
'CBE325ABBD44C58723A7268F7FB90D49',
|
||||
];
|
||||
|
||||
protected static array $additionalPerks = [
|
||||
|
|
@ -40,16 +40,16 @@ class InkedItemConfig extends CharacterItemConfig
|
|||
'5AE771024971ED9C8DE3188A30BE3946',
|
||||
'180B90BC4577469F4D52DA917A7FED6B',
|
||||
'CB95BEF142FE7EEAA6D9828DE3E4D6EA',
|
||||
'04650B23493C386FA87E48947D26D79F',
|
||||
'168A9C7E4AF1C1D321885ABEF7538DE9',
|
||||
'F329A7724E21169E99739196DFC797D1',
|
||||
'03B907684E4B8058A274F1A1958A7FB2',
|
||||
'B245A69F4145075488DD01A477A24385',
|
||||
'72F7A311494D090473C38C8391AC6F89',
|
||||
'AD024E8E46E056286FC5F0AB07EC2FA0',
|
||||
'3A769A1F400DC24C97DF28B8969992E1',
|
||||
'AC4E66024C3E56B3675EA1B273AB7B6E',
|
||||
'B377AE6047A4688FE2164FB2E341C525',
|
||||
'9FCAAC9143A827E79DC179B762B1E520',
|
||||
'9A9042614697C385E5744C903F5E19C3',
|
||||
'25B8F52744CAEB17E599888B5E80162E',
|
||||
'EAC46B4C4979624CD3C15B9189D1CC93',
|
||||
'2822F9B547761DD69A4853920A5A3A67',
|
||||
'46686C2F49C88ADD7635A4B3D5B1D594',
|
||||
'FF5821084098286D2E31E99192BB0988',
|
||||
'77EF1CAC48919368F529018D6E512B94',
|
||||
'6BABAFD74690D55F470764A1ACC7DFE1',
|
||||
'67B8A74643EA6CB8A41457AD5A576D69',
|
||||
'6340FA564B0C4E692AD174BB743607F5',
|
||||
'418880784C86E2A81AB395A998B09901',
|
||||
'75831C73438DA8C3E873339E58FC1674',
|
||||
|
|
@ -90,7 +90,6 @@ class InkedItemConfig extends CharacterItemConfig
|
|||
'F2F5C6BB4536127CD0D0768422BCF154',
|
||||
'DFF40D824EDD8D0EF7DC4EBE81E7D121',
|
||||
'5EEF1C6040DE7AB766F9E48795BD0500',
|
||||
|
||||
];
|
||||
|
||||
protected static array $additionalWeapons = [
|
||||
|
|
|
|||
|
|
@ -30,16 +30,16 @@ class SawbonesItemConfig extends CharacterItemConfig
|
|||
];
|
||||
|
||||
protected static array $additionalPerks = [
|
||||
'9FCAAC9143A827E79DC179B762B1E520',
|
||||
'9A9042614697C385E5744C903F5E19C3',
|
||||
'25B8F52744CAEB17E599888B5E80162E',
|
||||
'EAC46B4C4979624CD3C15B9189D1CC93',
|
||||
'2822F9B547761DD69A4853920A5A3A67',
|
||||
'46686C2F49C88ADD7635A4B3D5B1D594',
|
||||
'FF5821084098286D2E31E99192BB0988',
|
||||
'77EF1CAC48919368F529018D6E512B94',
|
||||
'6BABAFD74690D55F470764A1ACC7DFE1',
|
||||
'67B8A74643EA6CB8A41457AD5A576D69',
|
||||
'04650B23493C386FA87E48947D26D79F',
|
||||
'168A9C7E4AF1C1D321885ABEF7538DE9',
|
||||
'F329A7724E21169E99739196DFC797D1',
|
||||
'03B907684E4B8058A274F1A1958A7FB2',
|
||||
'B245A69F4145075488DD01A477A24385',
|
||||
'72F7A311494D090473C38C8391AC6F89',
|
||||
'AD024E8E46E056286FC5F0AB07EC2FA0',
|
||||
'3A769A1F400DC24C97DF28B8969992E1',
|
||||
'AC4E66024C3E56B3675EA1B273AB7B6E',
|
||||
'B377AE6047A4688FE2164FB2E341C525',
|
||||
'274EB0B34AB39E468BFA878F7E87465B',
|
||||
'4AE4801A440EFF8B54760EBFF92B128C',
|
||||
'42E05FC94E6B09CCBB6208BAF94AE98F',
|
||||
|
|
@ -90,7 +90,6 @@ class SawbonesItemConfig extends CharacterItemConfig
|
|||
'E3139A504D205C06438904B1ECD68D44',
|
||||
'E9564AFF410C3F82BD53B7890DA9DB97',
|
||||
'A1463E12485BA0B2D678EA863BCC8ED9',
|
||||
|
||||
];
|
||||
|
||||
protected static array $additionalWeapons = [
|
||||
|
|
|
|||
52
dist/app/Classes/Config/CatalogPriceConfig.php
vendored
52
dist/app/Classes/Config/CatalogPriceConfig.php
vendored
|
|
@ -131,49 +131,61 @@ class CatalogPriceConfig
|
|||
|
||||
const PERKS_COST = [
|
||||
1 => [
|
||||
'CurrencyA' => 500,
|
||||
'CurrencyB' => 500,
|
||||
],
|
||||
2 => [
|
||||
'CurrencyB' => 750,
|
||||
'CurrencyA' => 700,
|
||||
'CurrencyB' => 800,
|
||||
],
|
||||
3 => [
|
||||
'CurrencyB' => 1000,
|
||||
'CurrencyA' => 900,
|
||||
'CurrencyB' => 1200,
|
||||
],
|
||||
4 => [
|
||||
'CurrencyB' => 1250,
|
||||
'CurrencyA' => 1100,
|
||||
'CurrencyB' => 1600,
|
||||
'CurrencyC' => 400,
|
||||
],
|
||||
5 => [
|
||||
'CurrencyB' => 1500,
|
||||
'CurrencyA' => 1300,
|
||||
'CurrencyB' => 2000,
|
||||
'CurrencyC' => 1100,
|
||||
],
|
||||
6 => [
|
||||
'CurrencyA' => 425,
|
||||
'CurrencyB' => 1300,
|
||||
'CurrencyA' => 1500,
|
||||
'CurrencyB' => 2400,
|
||||
'CurrencyC' => 1700,
|
||||
],
|
||||
7 => [
|
||||
'CurrencyA' => 525,
|
||||
'CurrencyB' => 1400,
|
||||
'CurrencyA' => 1700,
|
||||
'CurrencyB' => 2900,
|
||||
'CurrencyC' => 2400,
|
||||
],
|
||||
8 => [
|
||||
'CurrencyA' => 625,
|
||||
'CurrencyB' => 1500,
|
||||
'CurrencyA' => 1900,
|
||||
'CurrencyB' => 3400,
|
||||
'CurrencyC' => 3100,
|
||||
],
|
||||
9 => [
|
||||
'CurrencyA' => 725,
|
||||
'CurrencyB' => 1600,
|
||||
'CurrencyA' => 2100,
|
||||
'CurrencyB' => 4000,
|
||||
'CurrencyC' => 3900,
|
||||
],
|
||||
10 => [
|
||||
'CurrencyA' => 825,
|
||||
'CurrencyB' => 1700,
|
||||
'CurrencyA' => 2300,
|
||||
'CurrencyB' => 4600,
|
||||
'CurrencyC' => 4700,
|
||||
],
|
||||
];
|
||||
|
||||
const SKINS_COST = [
|
||||
ItemQuality::Basic->value => ['CurrencyC' => 2500],
|
||||
ItemQuality::Specialized->value => ['CurrencyC' => 3500],
|
||||
ItemQuality::Rare->value => ['CurrencyC' => 4500],
|
||||
ItemQuality::Superior->value => ['CurrencyC' => 5500],
|
||||
ItemQuality::Epic->value => ['CurrencyC' => 6250],
|
||||
ItemQuality::Ultra->value => ['CurrencyC' => 7500],
|
||||
ItemQuality::Basic->value => ['CurrencyA' => 800, 'CurrencyC'=> 1200],
|
||||
ItemQuality::Specialized->value => ['CurrencyA' => 1600, 'CurrencyC' => 1900],
|
||||
ItemQuality::Rare->value => ['CurrencyA' => 2400, 'CurrencyC' => 2600],
|
||||
ItemQuality::Superior->value => ['CurrencyA' => 3200, 'CurrencyC' => 3000],
|
||||
ItemQuality::Epic->value => ['CurrencyA' => 4000, 'CurrencyC' => 5400],
|
||||
ItemQuality::Ultra->value => ['CurrencyA' => 6000, 'CurrencyC' => 8500],
|
||||
];
|
||||
|
||||
public static function GetCategoryPriceForLevel(CatalogPriceCategory $category, int|string $level): array
|
||||
|
|
|
|||
172
dist/app/Classes/Factory/TimedChallengeFactory.php
vendored
Normal file
172
dist/app/Classes/Factory/TimedChallengeFactory.php
vendored
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
<?php
|
||||
|
||||
namespace App\Classes\Factory;
|
||||
|
||||
use App\Enums\Game\ChallengeType;
|
||||
use App\Enums\Game\Faction;
|
||||
use App\Enums\Game\RewardType;
|
||||
use App\Exceptions\TimedChallengeFactoryException;
|
||||
use App\Http\Responses\Api\General\Reward;
|
||||
use App\Models\Game\TimedChallenge;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
abstract class TimedChallengeFactory
|
||||
{
|
||||
const AVAILABLE_DAILY_RUNNER = [
|
||||
'/Game/Challenges/Weekly/Challenge_BleedOut_RunnerWeekly.Challenge_BleedOut_RunnerWeekly' => 1,
|
||||
'/Game/Challenges/Challenge_JustPlay.Challenge_JustPlay' => 1,
|
||||
'/Game/Challenges/Challenge_Deliver_Runner.Challenge_Deliver_Runner' => 15,
|
||||
'/Game/Challenges/Weekly/Challenge_Shields_RunnerWeekly.Challenge_Shields_RunnerWeekly' => 10,
|
||||
'/Game/Challenges/Progression/General/Challenge_Heal_Runner.Challenge_Heal_Runner.' => 100,
|
||||
'/Game/Challenges/Progression/General/Challenge_Evade_Runner.Challenge_Evade_Runner' => 25,
|
||||
] ;
|
||||
|
||||
const AVAILABLE_DAILY_HUNTER = [
|
||||
'/Game/Challenges/Challenge_JustPlay.Challenge_JustPlay' => 1,
|
||||
'/Game/Challenges/Weekly/Challenge_DroneActivation_HunterWeekly.Challenge_DroneActivation_HunterWeekly' => 5,
|
||||
'/Game/Challenges/Weekly/Challenge_Headshot_HunterWeekly.Challenge_Headshot_HunterWeekly' => 1,
|
||||
'/Game/Challenges/Challenge_Down_Hunter.Challenge_Down_Hunter' => 3,
|
||||
'/Game/Challenges/Weekly/Challenge_InDenial_HunterWeekly.Challenge_InDenial_HunterWeekly' => 3,
|
||||
];
|
||||
|
||||
const AVAILABLE_WEEKLY_RUNNER = [
|
||||
'/Game/Challenges/Weekly/Challenge_BleedOut_RunnerWeekly.Challenge_BleedOut_RunnerWeekly' => 5,
|
||||
'/Game/Challenges/Weekly/Challenge_Greed_RunnerWeekly.Challenge_Greed_RunnerWeekly' => 50,
|
||||
'/Game/Challenges/Weekly/Challenge_Shields_RunnerWeekly.Challenge_Shields_RunnerWeekly' => 100,
|
||||
'/Game/Challenges/Challenge_Deliver_Runner.Challenge_Deliver_Runner' => 150,
|
||||
'/Game/Challenges/Weekly/Challenge_SpeedCapture_RunnerWeekly.Challenge_SpeedCapture_RunnerWeekly' => 15,
|
||||
'/Game/Challenges/Weekly/Challenge_UPs_RunnerWeekly.Challenge_UPs_RunnerWeekly' => 5,
|
||||
'/Game/Challenges/Weekly/Challenge_Wasteful_RunnerWeekly.Challenge_Wasteful_RunnerWeekly' => 100,
|
||||
'/Game/Challenges/Challenge_JustPlay.Challenge_JustPlay' => 5,
|
||||
'/Game/Challenges/Progression/General/Challenge_Heal_Runner.Challenge_Heal_Runner' => 600,
|
||||
'/Game/Challenges/Progression/General/Challenge_Evade_Runner.Challenge_Evade_Runner' => 150,
|
||||
];
|
||||
|
||||
const AVAILABLE_WEEKLY_HUNTER = [
|
||||
'/Game/Challenges/Weekly/Challenge_ARB_Damage_HunterWeekly.Challenge_ARB_Damage_HunterWeekly' => 5000,
|
||||
'/Game/Challenges/Weekly/Challenge_AssaultRifleWins_HunterWeekly.Challenge_AssaultRifleWins_HunterWeekly' => 100,
|
||||
'/Game/Challenges/Weekly/Challenge_Damage_HunterWeekly.Challenge_Damage_HunterWeekly' => 5000,
|
||||
'/Game/Challenges/Weekly/Challenge_DroneActivation_HunterWeekly.Challenge_DroneActivation_HunterWeekly' => 25,
|
||||
'/Game/Challenges/Weekly/Challenge_Greed_HunterWeekly.Challenge_Greed_HunterWeekly' => 50,
|
||||
'/Game/Challenges/Weekly/Challenge_Headshot_HunterWeekly.Challenge_Headshot_HunterWeekly' => 10,
|
||||
'/Game/Challenges/Weekly/Challenge_HuntingShotgunWins_HunterWeekly.Challenge_HuntingShotgunWins_HunterWeekly' => 10,
|
||||
'/Game/Challenges/Weekly/Challenge_InDenial_HunterWeekly.Challenge_InDenial_HunterWeekly' => 20,
|
||||
'/Game/Challenges/Weekly/Challenge_LMGWins_HunterWeekly.Challenge_LMGWins_HunterWeekly' => 10,
|
||||
'/Game/Challenges/Weekly/Challenge_Reveals_hunterWeekly.Challenge_Reveals_hunterWeekly' => 10,
|
||||
'/Game/Challenges/Weekly/Challenge_RingOut_hunterWeekly.Challenge_RingOut_hunterWeekly' => 5,
|
||||
'/Game/Challenges/Weekly/Challenge_Mines_HunterWeekly.Challenge_Mines_HunterWeekly' => 10,
|
||||
'/Game/Challenges/Weekly/Challenge_ShotgunDowns_HunterWeekly.Challenge_ShotgunDowns_HunterWeekly' => 10,
|
||||
'/Game/Challenges/Weekly/Challenge_Wasteful_HunterWeekly.Challenge_Wasteful_HunterWeekly' => 100,
|
||||
'/Game/Challenges/Challenge_JustPlay.Challenge_JustPlay' => 5,
|
||||
];
|
||||
|
||||
const DAILY_REWARDS = [
|
||||
'CurrencyA' => [
|
||||
'min' => 1000,
|
||||
'max' => 2500,
|
||||
],
|
||||
'CurrencyB' => [
|
||||
'min' => 250,
|
||||
'max' => 500,
|
||||
],
|
||||
'CurrencyC' => [
|
||||
'min' => 500,
|
||||
'max' => 750,
|
||||
],
|
||||
];
|
||||
|
||||
const WEEKLY_REWARDS = [
|
||||
'CurrencyA' => [
|
||||
'min' => 3000,
|
||||
'max' => 5000,
|
||||
],
|
||||
'CurrencyB' => [
|
||||
'min' => 250,
|
||||
'max' => 350,
|
||||
],
|
||||
'CurrencyC' => [
|
||||
'min' => 600,
|
||||
'max' => 900,
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* Makes a new TimedChallenge Instance that's not yet saved to the Database.
|
||||
*
|
||||
* @param Carbon $startTime
|
||||
* @param Faction $faction
|
||||
* @param ChallengeType $type
|
||||
* @return void
|
||||
* @throws TimedChallengeFactoryException
|
||||
*/
|
||||
public static function makeChallenge(
|
||||
Carbon $startTime,
|
||||
Faction $faction,
|
||||
ChallengeType $type,
|
||||
): TimedChallenge
|
||||
{
|
||||
[$blueprintPath, $completionValue] = static::pickChallenge($faction, $type);
|
||||
|
||||
$challenge = new TimedChallenge();
|
||||
$challenge->type = $type;
|
||||
$challenge->faction = $faction;
|
||||
$challenge->blueprint_path = $blueprintPath;
|
||||
$challenge->completion_value = $completionValue;
|
||||
|
||||
$challenge->start_time = $startTime;
|
||||
|
||||
if($type === ChallengeType::Daily)
|
||||
$challenge->end_time = $startTime->copy()->addDay();
|
||||
else
|
||||
$challenge->end_time = $startTime->copy()->addWeek();
|
||||
|
||||
$challenge->rewards = [static::pickReward($type)];
|
||||
|
||||
return $challenge;
|
||||
}
|
||||
|
||||
protected static function pickChallenge(
|
||||
Faction $faction,
|
||||
ChallengeType $type,
|
||||
): array {
|
||||
$challengeArray = match ($faction) {
|
||||
Faction::Hunter => $type === ChallengeType::Daily ? static::AVAILABLE_DAILY_HUNTER : static::AVAILABLE_WEEKLY_HUNTER,
|
||||
Faction::Runner => $type === ChallengeType::Daily ? static::AVAILABLE_DAILY_RUNNER : static::AVAILABLE_WEEKLY_RUNNER,
|
||||
default => null,
|
||||
};
|
||||
|
||||
if($challengeArray === null)
|
||||
throw new TimedChallengeFactoryException('Unallowed Faction ('. $faction->value .'), could not select a challenge.');
|
||||
|
||||
$blueprintPath = array_rand($challengeArray);
|
||||
$completionValue = $challengeArray[$blueprintPath];
|
||||
|
||||
return [$blueprintPath, $completionValue];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ChallengeType $type
|
||||
* @return Reward
|
||||
* @throws TimedChallengeFactoryException
|
||||
*/
|
||||
protected static function pickReward(
|
||||
ChallengeType $type,
|
||||
): Reward {
|
||||
$rewardsArray = match ($type) {
|
||||
ChallengeType::Daily => static::DAILY_REWARDS,
|
||||
ChallengeType::Weekly => static::WEEKLY_REWARDS,
|
||||
default => null,
|
||||
};
|
||||
|
||||
if($rewardsArray === null)
|
||||
throw new TimedChallengeFactoryException('Unallowed Challenge Type (' . $type->value . '), could not select a reward.');
|
||||
|
||||
$pickedReward = array_rand($rewardsArray);
|
||||
|
||||
return new Reward(
|
||||
RewardType::Currency,
|
||||
round(rand($rewardsArray[$pickedReward]['min'], $rewardsArray[$pickedReward]['max']) / 10) * 10,
|
||||
$pickedReward,
|
||||
);
|
||||
}
|
||||
}
|
||||
33
dist/app/Classes/Frontend/ChatMessage.php
vendored
Normal file
33
dist/app/Classes/Frontend/ChatMessage.php
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace App\Classes\Frontend;
|
||||
|
||||
use App\View\Components\Auth\User;
|
||||
use Illuminate\Support\Carbon;
|
||||
use JsonSerializable;
|
||||
|
||||
class ChatMessage implements JsonSerializable
|
||||
{
|
||||
public function __construct(
|
||||
public string $gameId,
|
||||
public string $userId,
|
||||
public Carbon $messageTime,
|
||||
public string $message,
|
||||
)
|
||||
{}
|
||||
|
||||
public function getUser(): ?\App\Models\User\User
|
||||
{
|
||||
return \App\Models\User\User::find($this->userId);
|
||||
}
|
||||
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return [
|
||||
'gameId' => $this->gameId,
|
||||
'userId' => $this->userId,
|
||||
'messageTime' => $this->messageTime->toJSON(),
|
||||
'message' => $this->message,
|
||||
];
|
||||
}
|
||||
}
|
||||
65
dist/app/Console/Commands/CleanupLogs.php
vendored
Normal file
65
dist/app/Console/Commands/CleanupLogs.php
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use DirectoryIterator;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Str;
|
||||
|
||||
class CleanupLogs extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'app:cleanup-logs';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Cleanup old log files.';
|
||||
|
||||
// Delete files older than this number of days.
|
||||
const FILE_DAYS_OLD = 14;
|
||||
|
||||
// Delete session files older than this number of days.
|
||||
const SESSION_FILE_DAYS_OLD = 7;
|
||||
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$disk = Storage::disk('logs');
|
||||
$files = $disk->allFiles();
|
||||
$now = Carbon::now();
|
||||
|
||||
// Delete older modified files
|
||||
foreach ($files as $file) {
|
||||
$lastModified = Carbon::createFromTimestamp($disk->lastModified($file));
|
||||
|
||||
if(Str::startsWith($file, 'sessions/'))
|
||||
$shouldDelete = $now->diff($lastModified)->total('days') * -1 > self::SESSION_FILE_DAYS_OLD;
|
||||
else
|
||||
$shouldDelete = $now->diff($lastModified)->total('days') * -1 > self::FILE_DAYS_OLD;
|
||||
|
||||
if($shouldDelete)
|
||||
$disk->delete($file);
|
||||
}
|
||||
|
||||
//Loop over all directories to delete empty ones.
|
||||
$directories = $disk->allDirectories();
|
||||
foreach ($directories as $directory) {
|
||||
$files = $disk->allFiles($directory);
|
||||
|
||||
if(count($files) === 0)
|
||||
$disk->deleteDirectory($directory);
|
||||
}
|
||||
}
|
||||
}
|
||||
94
dist/app/Console/Commands/GenerateTimedChallenges.php
vendored
Normal file
94
dist/app/Console/Commands/GenerateTimedChallenges.php
vendored
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Classes\Factory\TimedChallengeFactory;
|
||||
use App\Enums\Game\ChallengeType;
|
||||
use App\Enums\Game\Faction;
|
||||
use App\Enums\Game\RewardType;
|
||||
use App\Exceptions\TimedChallengeFactoryException;
|
||||
use App\Http\Responses\Api\General\Reward;
|
||||
use App\Models\Game\TimedChallenge;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class GenerateTimedChallenges extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'app:generate-timed-challenges';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Generate the Daily and Weekly challenges for the upcoming day/week';
|
||||
|
||||
const INTERVAL_HOUR = 21;
|
||||
const INTERVAL_MINUTE = 0;
|
||||
|
||||
const WEEKLY_INTERVAL_DAY = 'tuesday';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$dailyToday = Carbon::today();
|
||||
$dailyToday->setTime(static::INTERVAL_HOUR, static::INTERVAL_MINUTE);
|
||||
|
||||
// Put the current Daily a day in the past when the current time the job runs is still before the new Daily
|
||||
if(Carbon::now()->isBefore($dailyToday))
|
||||
$dailyToday->subDay();
|
||||
|
||||
$dailyTomorrow = $dailyToday->copy()->addDay();
|
||||
$currentWeekly = Carbon::parse('last '.static::WEEKLY_INTERVAL_DAY);
|
||||
$currentWeekly->setTime(static::INTERVAL_HOUR, static::INTERVAL_MINUTE);
|
||||
$nextWeekly = $currentWeekly->copy()->addWeek();
|
||||
|
||||
$dailys = [$dailyToday, $dailyTomorrow];
|
||||
$weeklys = [$currentWeekly, $nextWeekly];
|
||||
|
||||
$log = Log::channel('challengeCreation');
|
||||
|
||||
foreach ([Faction::Hunter, Faction::Runner] as $faction) {
|
||||
foreach ($dailys as $time) {
|
||||
$dailyExists = TimedChallenge::whereDate('start_time', $time)
|
||||
->where('type', ChallengeType::Daily)
|
||||
->where('faction', $faction)
|
||||
->exists();
|
||||
|
||||
if(!$dailyExists) {
|
||||
try {
|
||||
$newDaily = TimedChallengeFactory::makeChallenge($time, $faction, ChallengeType::Daily);
|
||||
$newDaily->save();
|
||||
} catch (TimedChallengeFactoryException $e) {
|
||||
$log->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($weeklys as $time) {
|
||||
$weeklyExists = TimedChallenge::whereDate('start_time', $time)
|
||||
->where('type', ChallengeType::Weekly)
|
||||
->where('faction', $faction)
|
||||
->exists();
|
||||
|
||||
if(!$weeklyExists) {
|
||||
try {
|
||||
$newDaily = TimedChallengeFactory::makeChallenge($time, $faction, ChallengeType::Weekly);
|
||||
$newDaily->save();
|
||||
} catch (TimedChallengeFactoryException $e) {
|
||||
$log->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
74
dist/app/Console/Commands/GiveAllUsersDefaultItems.php
vendored
Normal file
74
dist/app/Console/Commands/GiveAllUsersDefaultItems.php
vendored
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Classes\Character\CharacterItemConfig;
|
||||
use App\Enums\Game\Characters;
|
||||
use App\Helper\Uuid\UuidHelper;
|
||||
use App\Models\User\PlayerData;
|
||||
use App\Models\User\User;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class GiveAllUsersDefaultItems extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'app:give-all-users-default-items {userId?}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Command description';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$userId = $this->argument('userId');
|
||||
if($userId === null)
|
||||
$playerDatas = PlayerData::all();
|
||||
else
|
||||
$playerDatas = [User::findOrFail($userId)->playerData()];
|
||||
|
||||
foreach ($playerDatas as $playerData) {
|
||||
foreach (Characters::cases() as $case) {
|
||||
$this->info('Adding items for user ' . $playerData->user_id . ' for Character ' . $case->value);
|
||||
$configClass = $case->getCharacter()->getItemConfigClass();
|
||||
$this->addItemsToUser($playerData, $configClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PlayerData $user
|
||||
* @param class-string<CharacterItemConfig> $config
|
||||
* @return void
|
||||
*/
|
||||
public function addItemsToUser(PlayerData &$playerData, string $config): void {
|
||||
$itemIds = [
|
||||
...$config::getDefaultEquippedBonuses(),
|
||||
...$config::getDefaultEquippedWeapons(),
|
||||
...$config::getDefaultEquipment(),
|
||||
...$config::getDefaultPowers(),
|
||||
...$config::getDefaultWeapons(),
|
||||
...$config::getDefaultEquippedPerks(),
|
||||
];
|
||||
|
||||
$itemIds = UuidHelper::convertFromHexToUuidCollecton($itemIds, true);
|
||||
try {
|
||||
$playerData->inventory()->syncWithoutDetaching($itemIds);
|
||||
} catch (QueryException $e) {
|
||||
Log::channel('single')->error($e->getMessage());
|
||||
$this->error('Exception: ' . $e->getMessage());
|
||||
$this->error("Failed to add items to inventory: " . json_encode($itemIds, JSON_PRETTY_PRINT));
|
||||
}
|
||||
}
|
||||
}
|
||||
39
dist/app/Console/Commands/ImportCatalog.php
vendored
39
dist/app/Console/Commands/ImportCatalog.php
vendored
|
|
@ -123,6 +123,45 @@ private function importChallenges(): void {
|
|||
}
|
||||
}
|
||||
|
||||
$achievementChallenges = [
|
||||
[
|
||||
'id' => 'e51981b9-46be-e3d4-5c5c-41b2fcff310b',
|
||||
'value' => 500,
|
||||
'path' => '/Game/Challenges/Challenge_Deliver_Runner.Challenge_Deliver_Runner',
|
||||
],
|
||||
[
|
||||
'id' => 'efab89e6-465d-1163-d62a-07b11048f2b6',
|
||||
'value' => 50,
|
||||
'path' => '/Game/Challenges/Challenge_JustPlay.Challenge_JustPlay',
|
||||
],
|
||||
[
|
||||
'id' => '2caebb35-4d50-6d7c-43b9-41bc1da775a0',
|
||||
'value' => 10,
|
||||
'path' => '/Game/Challenges/Progression/General/Challenge_Exit_Runner.Challenge_Exit_Runner',
|
||||
],
|
||||
[
|
||||
'id' => 'aad05b9d-4647-1dc8-11bb-e0ba91916ab7',
|
||||
'value' => 50,
|
||||
'path' => '/Game/Challenges/Challenge_Down_Hunter.Challenge_Down_Hunter',
|
||||
],
|
||||
[
|
||||
'id' => 'ba2d4a54-45cb-7027-6a8f-5d9e1afce080',
|
||||
'value' => 100,
|
||||
'path' => '/Game/Challenges/Challenge_DroneCharger_Hunter.Challenge_DroneCharger_Hunter',
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($achievementChallenges as $challenge) {
|
||||
$newChallenge = Challenge::findOrNew($challenge['id']);
|
||||
|
||||
$newChallenge->id = $challenge['id'];
|
||||
$newChallenge->completion_value = $challenge['value'];
|
||||
$newChallenge->asset_path = $challenge['path'];
|
||||
|
||||
$this->info('Importing Achievement Challenge: '.$challenge['id']);
|
||||
$newChallenge->save();
|
||||
}
|
||||
|
||||
$this->info('Finished importing challenges.');
|
||||
}
|
||||
|
||||
|
|
|
|||
15
dist/app/Console/Commands/MatchmakingCleanup.php
vendored
15
dist/app/Console/Commands/MatchmakingCleanup.php
vendored
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Enums\Game\Faction;
|
||||
use App\Enums\Game\Matchmaking\MatchStatus;
|
||||
use App\Models\Game\Matchmaking\Game;
|
||||
use App\Models\Game\Matchmaking\QueuedPlayer;
|
||||
|
|
@ -39,7 +40,7 @@ class MatchmakingCleanup extends Command
|
|||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): void
|
||||
{
|
||||
$log = Log::channel('matchmaking_cleanup');
|
||||
|
||||
|
|
@ -50,12 +51,18 @@ public function handle()
|
|||
|
||||
$log->info('Queued players: ' . json_encode($cleanedQueuedPlayers, JSON_PRETTY_PRINT));
|
||||
|
||||
$deletedClosedGames = Game::where('status', '=', MatchStatus::Closed->value)
|
||||
$closedGamesToKill = Game::where('status', '=', MatchStatus::Closed->value)
|
||||
->where('updated_at', '<', Carbon::now()->subSeconds(static::GAME_MAX_TIME * 60))
|
||||
->delete();
|
||||
->get();
|
||||
|
||||
$log->info('Deleted Closed games: ' . json_encode($deletedClosedGames, JSON_PRETTY_PRINT));
|
||||
foreach ($closedGamesToKill as $game) {
|
||||
//archive the games set to closed, so we don't lose the chat history
|
||||
$game->archiveGame(Faction::None);
|
||||
$game->status = MatchStatus::Killed;
|
||||
$game->save();
|
||||
}
|
||||
|
||||
$log->info('Closed games set to Killed: ' . json_encode($closedGamesToKill->getQueueableIds(), JSON_PRETTY_PRINT));
|
||||
|
||||
// delete games where the hunter crashed on loading into the arena, leaving the game stuck at created
|
||||
$deletedCreatedGames = Game::where('status', '=', MatchStatus::Created)
|
||||
|
|
|
|||
31
dist/app/Console/Commands/ProcessMatchmaking.php
vendored
31
dist/app/Console/Commands/ProcessMatchmaking.php
vendored
|
|
@ -5,16 +5,23 @@
|
|||
use App\Classes\Matchmaking\MatchmakingPlayerCount;
|
||||
use App\Enums\Game\Matchmaking\MatchmakingSide;
|
||||
use App\Enums\Game\Matchmaking\MatchStatus;
|
||||
use App\Models\Admin\MatchmakingSettings;
|
||||
use App\Models\Game\Matchmaking\Game;
|
||||
use App\Models\Game\Matchmaking\MatchConfiguration;
|
||||
use App\Models\Game\Matchmaking\QueuedPlayer;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Log;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class ProcessMatchmaking extends Command
|
||||
{
|
||||
public static int $repeatTimeSeconds = 10;
|
||||
|
||||
const ONE_VS_FOUR_AND_VS_FIVE_FIRST_ATTEMPT_CACHE_KEY = 'matchmaking_attempt_1v4_1v5';
|
||||
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
|
|
@ -36,6 +43,7 @@ class ProcessMatchmaking extends Command
|
|||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
$matchmakingSettings = MatchmakingSettings::get();
|
||||
// Select all queued Players/party leaders, descending by party size
|
||||
$players = QueuedPlayer::withCount('followingUsers')
|
||||
->sharedLock()
|
||||
|
|
@ -78,12 +86,33 @@ public function handle(): void
|
|||
));
|
||||
|
||||
$playerCount = $this->getTotalPlayersCount($players);
|
||||
|
||||
// If we only have one Hunter and could make a 1v4 or 1v5 we want to wait a bit before making a match.
|
||||
// because there could be some runners not being fast enough in queue or the matchmaking command running unfortunatly while players are queuing up.
|
||||
if ($playerCount->hunters === 1 && ($playerCount->runners === 4 || $playerCount->runners === 5)) {
|
||||
if (Cache::has(static::ONE_VS_FOUR_AND_VS_FIVE_FIRST_ATTEMPT_CACHE_KEY)) {
|
||||
/** @var Carbon $firstAttempt */
|
||||
$firstAttempt = Cache::get(static::ONE_VS_FOUR_AND_VS_FIVE_FIRST_ATTEMPT_CACHE_KEY);
|
||||
if ($firstAttempt->diffInSeconds(Carbon::now()) < $matchmakingSettings->matchWaitingTime){
|
||||
return;
|
||||
}
|
||||
Cache::forget(static::ONE_VS_FOUR_AND_VS_FIVE_FIRST_ATTEMPT_CACHE_KEY);
|
||||
}
|
||||
else {
|
||||
Cache::set(static::ONE_VS_FOUR_AND_VS_FIVE_FIRST_ATTEMPT_CACHE_KEY, Carbon::now());
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Cache::forget(static::ONE_VS_FOUR_AND_VS_FIVE_FIRST_ATTEMPT_CACHE_KEY);
|
||||
}
|
||||
|
||||
$availableMatchConfigs = MatchConfiguration::getAvailableMatchConfigs($playerCount->runners, $playerCount->hunters);
|
||||
|
||||
if($availableMatchConfigs->isEmpty())
|
||||
return;
|
||||
|
||||
$selectedConfig = MatchConfiguration::selectRandomConfigByWeight($availableMatchConfigs);
|
||||
$selectedConfig = MatchConfiguration::selectMatchConfig($availableMatchConfigs, $playerCount->runners, $playerCount->hunters);
|
||||
|
||||
// Should never happen, but just to be careful
|
||||
if($selectedConfig === null)
|
||||
|
|
|
|||
73
dist/app/Console/Commands/SetCurrencyModifiers.php
vendored
Normal file
73
dist/app/Console/Commands/SetCurrencyModifiers.php
vendored
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Admin\CurrencyMultipliers;
|
||||
use App\Models\Game\Matchmaking\MatchConfiguration;
|
||||
use App\Models\Game\Messages\News;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class SetCurrencyModifiers extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'app:set-currency-modifiers';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Sets automated currency modifiers and news announcement for a timeframe';
|
||||
|
||||
const DAILY_START_TIME = '00:00';
|
||||
|
||||
const DAILY_END_TIME = '09:00';
|
||||
|
||||
const MODIFIER_AMOUNT = 1.5;
|
||||
|
||||
const GAME_NEWS_ID = '9f6a2801-c8c2-40ae-8d55-5dab3b601863';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$startTime = Carbon::today()->setTimeFromTimeString(static::DAILY_START_TIME);
|
||||
$endTime = Carbon::today()->setTimeFromTimeString(static::DAILY_END_TIME);
|
||||
|
||||
if(Carbon::now()->between($startTime, $endTime)) {
|
||||
$this->setModifiers(static::MODIFIER_AMOUNT);
|
||||
$this->setGamenewsVisibility(true);
|
||||
}
|
||||
else {
|
||||
$this->setModifiers(1);
|
||||
$this->setGamenewsVisibility(false);
|
||||
}
|
||||
}
|
||||
|
||||
private function setGamenewsVisibility(bool $enabled): void
|
||||
{
|
||||
$news = News::find(static::GAME_NEWS_ID);
|
||||
|
||||
if($news === null)
|
||||
return;
|
||||
|
||||
$news->enabled = $enabled;
|
||||
$news->save();
|
||||
}
|
||||
|
||||
private function setModifiers(float $modifier): void {
|
||||
$config = CurrencyMultipliers::get();
|
||||
|
||||
$config->currencyA = $modifier;
|
||||
$config->currencyB = $modifier;
|
||||
$config->currencyC = $modifier;
|
||||
|
||||
$config->save();
|
||||
}
|
||||
}
|
||||
7
dist/app/Console/Kernel.php
vendored
7
dist/app/Console/Kernel.php
vendored
|
|
@ -13,8 +13,11 @@ class Kernel extends ConsoleKernel
|
|||
protected function schedule(Schedule $schedule): void
|
||||
{
|
||||
$schedule->command('model:prune')->daily();
|
||||
$schedule->command('matchmaking:process')->everyFiveSeconds();
|
||||
$schedule->command('matchmaking:cleanup')->everyFifteenSeconds();
|
||||
$schedule->command('matchmaking:process')->everyTenSeconds();
|
||||
$schedule->command('matchmaking:cleanup')->everyThirtySeconds();
|
||||
$schedule->command('app:generate-timed-challenges')->daily();
|
||||
$schedule->command('app:cleanup-logs')->daily();
|
||||
$schedule->command('app:set-currency-modifiers')->hourlyAt(1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
11
dist/app/Enums/Game/ChallengeType.php
vendored
Normal file
11
dist/app/Enums/Game/ChallengeType.php
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums\Game;
|
||||
|
||||
enum ChallengeType: string
|
||||
{
|
||||
case None = 'None';
|
||||
case Daily = 'Daily';
|
||||
case Weekly = 'Weekly';
|
||||
case Event = 'Event';
|
||||
}
|
||||
5
dist/app/Enums/Game/Hunter.php
vendored
5
dist/app/Enums/Game/Hunter.php
vendored
|
|
@ -41,7 +41,10 @@ public function getGroupType(): ItemGroupType
|
|||
};
|
||||
}
|
||||
|
||||
public function getItemConfigClass(): string|CharacterItemConfig
|
||||
/**
|
||||
* @return class-string<CharacterItemConfig>
|
||||
*/
|
||||
public function getItemConfigClass(): string
|
||||
{
|
||||
return match ($this) {
|
||||
Hunter::Stalker => StalkerItemConfig::class,
|
||||
|
|
|
|||
6
dist/app/Enums/Game/RewardType.php
vendored
6
dist/app/Enums/Game/RewardType.php
vendored
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
enum RewardType: string
|
||||
{
|
||||
case Currency = 'Currency';
|
||||
case Inventory = 'Inventory';
|
||||
case Progression = 'Progression';
|
||||
case Currency = 'currency';
|
||||
case Inventory = 'inventory';
|
||||
case Progression = 'progression';
|
||||
}
|
||||
|
|
|
|||
5
dist/app/Enums/Game/Runner.php
vendored
5
dist/app/Enums/Game/Runner.php
vendored
|
|
@ -49,7 +49,10 @@ public function getGroupType(): ItemGroupType
|
|||
};
|
||||
}
|
||||
|
||||
public function getItemConfigClass(): string|CharacterItemConfig
|
||||
/**
|
||||
* @return class-string<CharacterItemConfig>
|
||||
*/
|
||||
public function getItemConfigClass(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::Smoke => FogItemConfig::class,
|
||||
|
|
|
|||
8
dist/app/Exceptions/TimedChallengeFactoryException.php
vendored
Normal file
8
dist/app/Exceptions/TimedChallengeFactoryException.php
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
class TimedChallengeFactoryException extends \Exception
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Http\Controllers\Api\Matchmaking;
|
||||
|
||||
use App\Console\Commands\ProcessMatchmaking;
|
||||
use App\Enums\Game\Matchmaking\MatchStatus;
|
||||
use App\Enums\Game\Matchmaking\QueueStatus;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
@ -16,6 +17,7 @@
|
|||
use App\Models\Admin\Archive\ArchivedGame;
|
||||
use App\Models\Admin\Archive\ArchivedPlayerProgression;
|
||||
use App\Models\Admin\CurrencyMultipliers;
|
||||
use App\Models\Admin\MatchmakingSettings;
|
||||
use App\Models\Admin\Versioning\CurrentGameVersion;
|
||||
use App\Models\Game\Matchmaking\Game;
|
||||
use App\Models\Game\Matchmaking\QueuedPlayer;
|
||||
|
|
@ -39,10 +41,10 @@ public function getRegions()
|
|||
|
||||
public function queue(QueueRequest $request)
|
||||
{
|
||||
if($request->category !== CurrentGameVersion::get()?->gameVersion)
|
||||
if ($request->category !== CurrentGameVersion::get()?->gameVersion)
|
||||
abort(403, 'Too old mod version');
|
||||
|
||||
if($request->checkOnly)
|
||||
if ($request->checkOnly)
|
||||
return json_encode($this->checkQueueStatus($request));
|
||||
|
||||
return json_encode($this->addPlayerToQueue($request));
|
||||
|
|
@ -52,20 +54,20 @@ public function cancelQueue(MatchmakingRequest $request)
|
|||
{
|
||||
$user = Auth::user();
|
||||
|
||||
if($user->id !== $request->playerId || $request->endState !== 'Cancelled')
|
||||
if ($user->id !== $request->playerId || $request->endState !== 'Cancelled')
|
||||
return response('', 204);
|
||||
|
||||
$lock = Cache::lock(static::QUEUE_LOCK, 10);
|
||||
|
||||
try {
|
||||
$lock->block(20 ,function () use (&$user) {
|
||||
$lock->block(20, function () use (&$user) {
|
||||
// Delete the player from the Queue
|
||||
QueuedPlayer::where('user_id', '=', $user->id)->delete();
|
||||
// And also from any game they are matched for.
|
||||
DB::table('game_user')->where('user_id', '=', $user->id)->delete();
|
||||
});
|
||||
} catch (LockTimeoutException $e) {
|
||||
Log::channel('matchmaking')->emergency('Queue Cancel: Could not acquire Lock for canceling user '.$user->id.'('.$user->last_known_username.')');
|
||||
Log::channel('matchmaking')->emergency('Queue Cancel: Could not acquire Lock for canceling user ' . $user->id . '(' . $user->last_known_username . ')');
|
||||
} finally {
|
||||
$lock->release();
|
||||
}
|
||||
|
|
@ -77,7 +79,7 @@ public function matchInfo(string $matchId)
|
|||
{
|
||||
$foundGame = Game::find($matchId);
|
||||
|
||||
if($foundGame === null)
|
||||
if ($foundGame === null)
|
||||
return ['status' => 'Error', 'message' => 'Match not found.'];
|
||||
|
||||
$user = Auth::user();
|
||||
|
|
@ -102,24 +104,24 @@ public function register(RegisterMatchRequest $request, string $matchId)
|
|||
return json_encode(MatchData::fromGame($foundGame));
|
||||
}
|
||||
|
||||
public function close($matchId)
|
||||
{
|
||||
$foundGame = Game::find($matchId);
|
||||
$foundGame->status = MatchStatus::Closed;
|
||||
$foundGame->save();
|
||||
public function close($matchId)
|
||||
{
|
||||
$foundGame = Game::find($matchId);
|
||||
$foundGame->status = MatchStatus::Closed;
|
||||
$foundGame->save();
|
||||
|
||||
return json_encode(MatchData::fromGame($foundGame));
|
||||
}
|
||||
return json_encode(MatchData::fromGame($foundGame));
|
||||
}
|
||||
|
||||
/*
|
||||
* Set a game to Quit state, Maybe exists but unsure since it never showed up in the request logs.
|
||||
*/
|
||||
public function quit($matchId)
|
||||
{
|
||||
$foundGame = Game::find($matchId);
|
||||
public function quit($matchId)
|
||||
{
|
||||
$foundGame = Game::find($matchId);
|
||||
$user = Auth::user();
|
||||
|
||||
if($foundGame->creator === $user) {
|
||||
if ($foundGame->creator === $user) {
|
||||
$foundGame->status = MatchStatus::Destroyed;
|
||||
$foundGame->save();
|
||||
}
|
||||
|
|
@ -128,17 +130,17 @@ public function quit($matchId)
|
|||
}
|
||||
|
||||
return response(null, 204);
|
||||
}
|
||||
}
|
||||
|
||||
public function kill($matchId)
|
||||
{
|
||||
$foundGame = Game::find($matchId);
|
||||
public function kill($matchId)
|
||||
{
|
||||
$foundGame = Game::find($matchId);
|
||||
|
||||
$response = json_encode(MatchData::fromGame($foundGame));
|
||||
$foundGame->delete();
|
||||
|
||||
return $response;
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function seedFileGet(string $gameVersion, string $seed, string $mapName)
|
||||
{
|
||||
|
|
@ -155,7 +157,7 @@ public function deleteUserFromMatch(Game $match, User $user)
|
|||
$requestUser = Auth::user();
|
||||
|
||||
// Block request if it doesn't come from the host
|
||||
if($match->creator->id != $requestUser->id)
|
||||
if ($match->creator->id != $requestUser->id)
|
||||
return response('Action not allowed, you are not the creator of the match.', 403);
|
||||
|
||||
$this->removeUserFromGame($user, $match);
|
||||
|
|
@ -165,13 +167,13 @@ public function deleteUserFromMatch(Game $match, User $user)
|
|||
|
||||
public function endOfMatch(EndOfMatchRequest $request)
|
||||
{
|
||||
if(ArchivedGame::archivedGameExists($request->matchId))
|
||||
if (ArchivedGame::archivedGameExists($request->matchId))
|
||||
return response('Match Already Closed', 209);
|
||||
|
||||
$game = Game::find($request->matchId);
|
||||
$user = Auth::user();
|
||||
|
||||
if($game->creator != $user)
|
||||
if ($game->creator != $user)
|
||||
return response('you are not the creator of the match.', 403);
|
||||
|
||||
$game->status = MatchStatus::Killed;
|
||||
|
|
@ -186,7 +188,7 @@ public function playerEndOfMatch(PlayerEndOfMatchRequest $request)
|
|||
$user = Auth::user();
|
||||
$game = Game::find($request->matchId);
|
||||
|
||||
if($game === null)
|
||||
if ($game === null)
|
||||
return response('Match not found.', 404);
|
||||
|
||||
if ($game->creator != $user)
|
||||
|
|
@ -194,21 +196,21 @@ public function playerEndOfMatch(PlayerEndOfMatchRequest $request)
|
|||
|
||||
$user = User::find($request->playerId);
|
||||
|
||||
if($user === null)
|
||||
if ($user === null)
|
||||
return response('User not found.', 404);
|
||||
|
||||
$lock = Cache::lock('playerEndOfMatch'.$user->id);
|
||||
$lock = Cache::lock('playerEndOfMatch' . $user->id);
|
||||
|
||||
try {
|
||||
// Lock the saving of the playerdata and stuff because the game can send multiple calls sometimes
|
||||
$lock->block(10 ,function () use (&$user, &$request, &$game) {
|
||||
if(ArchivedPlayerProgression::archivedPlayerExists($game->id, $user->id))
|
||||
if (ArchivedPlayerProgression::archivedPlayerExists($game->id, $user->id))
|
||||
return;
|
||||
|
||||
$playerData = $user->playerData();
|
||||
$characterData = $playerData->characterDataForCharacter($request->characterGroup->getCharacter());
|
||||
|
||||
if($request->hasQuit)
|
||||
if ($request->hasQuit)
|
||||
$playerData->quitterState->addQuitterPenalty();
|
||||
else
|
||||
$playerData->quitterState->addStayedMatch($playerData);
|
||||
|
|
@ -277,7 +279,7 @@ protected function checkQueueStatus(QueueRequest $request): QueueResponse
|
|||
$foundQueuedPlayer = QueuedPlayer::firstWhere('user_id', '=', $user->id);
|
||||
|
||||
// If we found a queued Player, return his status
|
||||
if($foundQueuedPlayer !== null) {
|
||||
if ($foundQueuedPlayer !== null) {
|
||||
// Set Last queue call time to remove players that maybe crashed or something
|
||||
// if they haven't sent a queue request in a long time.
|
||||
$foundQueuedPlayer->updated_at = Carbon::now();
|
||||
|
|
@ -287,7 +289,7 @@ protected function checkQueueStatus(QueueRequest $request): QueueResponse
|
|||
$response->status = QueueStatus::Queued;
|
||||
$response->queueData = new QueueData(
|
||||
1,
|
||||
10
|
||||
static::getETA(),
|
||||
);
|
||||
|
||||
return $response;
|
||||
|
|
@ -297,12 +299,13 @@ protected function checkQueueStatus(QueueRequest $request): QueueResponse
|
|||
// Only search for Created or open matches
|
||||
$foundGame = $user->activeGames();
|
||||
// If they also aren't in a game, add them to the queue again
|
||||
if($foundGame->count() < 1) {
|
||||
if ($foundGame->count() < 1) {
|
||||
$this->addPlayerToQueue($request);
|
||||
$response = new QueueResponse();
|
||||
$response->status = QueueStatus::Queued;
|
||||
$response->queueData = new QueueData(
|
||||
1,
|
||||
static::getETA(),
|
||||
);
|
||||
|
||||
return $response;
|
||||
|
|
@ -316,10 +319,10 @@ protected function checkQueueStatus(QueueRequest $request): QueueResponse
|
|||
|
||||
$response = new QueueResponse();
|
||||
|
||||
if($foundGame->status === MatchStatus::Opened) {
|
||||
if ($foundGame->status === MatchStatus::Opened) {
|
||||
$response->queueData = new QueueData(
|
||||
1,
|
||||
1
|
||||
static::getETA(),
|
||||
);
|
||||
}
|
||||
$response->status = QueueStatus::Matched;
|
||||
|
|
@ -334,7 +337,7 @@ protected function addPlayerToQueue(QueueRequest $request)
|
|||
$user = Auth::user();
|
||||
|
||||
// Remove user from any game he has previously joined.
|
||||
if($user->activeGames()->exists()) {
|
||||
if ($user->activeGames()->exists()) {
|
||||
$games = $user->activeGames()->get();
|
||||
foreach ($games as $game) {
|
||||
$this->removeUserFromGame($user, $game);
|
||||
|
|
@ -368,10 +371,26 @@ protected function removeUserFromGame(User $user, Game $game)
|
|||
{
|
||||
$game->players()->detach($user);
|
||||
|
||||
if($game->players->count() !== 0)
|
||||
// Delete the game if the creator deletes themselfes sice we had one case where the matchmaking broke due to a game being stuck like this.
|
||||
if ($game->players->count() !== 0 && $game->creator_user_id !== $user->id)
|
||||
return;
|
||||
|
||||
$game->delete();
|
||||
}
|
||||
|
||||
protected static function getETA(): int {
|
||||
if(Cache::has(ProcessMatchmaking::ONE_VS_FOUR_AND_VS_FIVE_FIRST_ATTEMPT_CACHE_KEY)) {
|
||||
$matchmakingSettings = MatchmakingSettings::get();
|
||||
/** @var Carbon $firstAttempt */
|
||||
$firstAttempt = Cache::get(ProcessMatchmaking::ONE_VS_FOUR_AND_VS_FIVE_FIRST_ATTEMPT_CACHE_KEY);
|
||||
$predictedMatchTime = $firstAttempt->copy();
|
||||
while ($firstAttempt->diffInSeconds($predictedMatchTime) < $matchmakingSettings->matchWaitingTime) {
|
||||
$predictedMatchTime->addSeconds(ProcessMatchmaking::$repeatTimeSeconds);
|
||||
}
|
||||
|
||||
return Carbon::now()->diffInSeconds($predictedMatchTime) * 1000;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,19 +2,26 @@
|
|||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Classes\Frontend\ChatMessage;
|
||||
use App\Enums\Game\Matchmaking\MatchStatus;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Api\Moderation\CheckChatMessageRequest;
|
||||
use App\Http\Requests\Api\Moderation\ReportPlayerRequest;
|
||||
use App\Http\Requests\Api\Player\CheckUsernameRequest;
|
||||
use App\Http\Responses\Api\Player\CheckUsernameResponse;
|
||||
use App\Models\Admin\BadChatMessage;
|
||||
use App\Models\Game\Matchmaking\Game;
|
||||
use App\Models\Game\Moderation\PlayerReport;
|
||||
use App\Models\User\User;
|
||||
use ConsoleTVs\Profanity\Builder;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Response;
|
||||
|
||||
class ModerationController extends Controller
|
||||
{
|
||||
const CHAT_CACHE_KEY = 'chat-messages-';
|
||||
|
||||
public function checkUsername(CheckUsernameRequest $request): mixed
|
||||
{
|
||||
|
|
@ -25,23 +32,39 @@ public function checkChatMessage(CheckChatMessageRequest $request): mixed
|
|||
{
|
||||
// Lobby Host that send the request to check the message. We log him too since only the lobby host checks the messages in teh backend.
|
||||
$hostUser = Auth::user();
|
||||
|
||||
$activeGame = $hostUser->games()->whereNotIn('status', [MatchStatus::Killed])->first();
|
||||
if($activeGame === null)
|
||||
// Don't log and check anything if the user is not in a game, we don't care about chatting in the locker room.
|
||||
return Response::json([]);
|
||||
|
||||
// User that send the chat message
|
||||
$messageUser = User::find($request->userId);
|
||||
|
||||
$gameMessages = Cache::get(static::CHAT_CACHE_KEY . $activeGame->id, []);
|
||||
$gameMessages[] = new ChatMessage(
|
||||
$activeGame->id,
|
||||
$messageUser->id,
|
||||
Carbon::now(),
|
||||
$request->message,
|
||||
);
|
||||
Cache::put(static::CHAT_CACHE_KEY . $activeGame->id, $gameMessages, 1800 /** 30 Minutes */);
|
||||
|
||||
$checker = Builder::blocker($request->message);
|
||||
|
||||
if($checker->clean())
|
||||
return response('{}');
|
||||
|
||||
$this->logBadMessage($hostUser, $messageUser, $request->message);
|
||||
$this->logBadMessage($hostUser, $messageUser, $request->message, $activeGame);
|
||||
return response('Bad Message >:(');
|
||||
}
|
||||
|
||||
public function logBadMessage(User $hostUser, User $messageUser, string $message): void {
|
||||
public function logBadMessage(User $hostUser, User $messageUser, string $message, Game $match): void {
|
||||
$badMessage = new BadChatMessage();
|
||||
$badMessage->hostUser()->associate($hostUser);
|
||||
$badMessage->user()->associate($messageUser);
|
||||
$badMessage->message = $message;
|
||||
$badMessage->match_id = $match->id;
|
||||
$badMessage->save();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ public function getFileWithPatchline(string $patchlineName, string $hash) : Bina
|
|||
if($gameFile === null)
|
||||
return response()->json('File not found', 404);
|
||||
|
||||
$filePath = DIRECTORY_SEPARATOR . str($patchlineName)->lower() . DIRECTORY_SEPARATOR . $gameFile->name;
|
||||
$filePath = DIRECTORY_SEPARATOR . str($patchlineName)->lower() . DIRECTORY_SEPARATOR . $gameFile->filename;
|
||||
|
||||
if (!$disk->exists($filePath)) {
|
||||
return response()->json('File not found', 404);
|
||||
|
|
@ -35,7 +35,7 @@ function getFile(string $hash) : BinaryFileResponse|JsonResponse {
|
|||
return $this->getFileWithPatchline(Patchline::LIVE->name, $hash);
|
||||
}
|
||||
|
||||
public function getGameFileList(string $patchlineName = null) : JsonResponse
|
||||
public function getGameFileList(?string $patchlineName = null) : JsonResponse
|
||||
{
|
||||
$patchline = Patchline::tryFromName(str($patchlineName)->upper()) ?? Patchline::LIVE;
|
||||
|
||||
|
|
@ -49,17 +49,35 @@ public function getGameFileList(string $patchlineName = null) : JsonResponse
|
|||
return response()->json(['error' => 'Unauthorized'], 401);
|
||||
}
|
||||
|
||||
$gameFiles = GameFile::select(['filename', 'hash', 'game_path', 'action'])
|
||||
->where('patchline', $patchline->value)
|
||||
->where('is_additional', 0)->latest()->get();
|
||||
$gameFiles = GameFile::where('patchline', $patchline->value)
|
||||
->where('is_additional', 0)
|
||||
->withFileHistory()
|
||||
->map(function ($latestFile) {
|
||||
$processedHashes = [];
|
||||
$history = collect();
|
||||
|
||||
foreach ($latestFile->children as $historyFile) {
|
||||
if (in_array($historyFile->hash, $processedHashes)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$processedHashes[] = $historyFile->hash;
|
||||
$history->push($historyFile->only(['hash']));
|
||||
}
|
||||
|
||||
$selectedFile = $latestFile->only(['filename', 'hash', 'game_path', 'action']);
|
||||
$selectedFile['history'] = $history;
|
||||
|
||||
return $selectedFile;
|
||||
});
|
||||
|
||||
if (count($gameFiles) <= 0)
|
||||
return response()->json(['error' => 'No files found'], 404);
|
||||
|
||||
return response()->json($gameFiles, 200);
|
||||
}
|
||||
|
||||
public function getGameModFileList(string $patchlineName = null) : JsonResponse
|
||||
|
||||
public function getGameModFileList(?string $patchlineName = null) : JsonResponse
|
||||
{
|
||||
$patchline = Patchline::tryFromName(str($patchlineName)->upper()) ?? Patchline::LIVE;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,19 +2,30 @@
|
|||
|
||||
namespace App\Http\Controllers\Api\Player;
|
||||
|
||||
use App\Enums\Game\RewardType;
|
||||
use App\Helper\Uuid\UuidHelper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Api\Player\ExecuteChallengeProgressionBatchRequest;
|
||||
use App\Http\Requests\Api\Player\GetChallengeProgressionBatchRequest;
|
||||
use App\Http\Requests\Api\Player\GetChallengesRequest;
|
||||
use App\Http\Responses\Api\General\Reward;
|
||||
use App\Http\Responses\Api\Player\Challenges\ChallengeProgressionBatchResponse;
|
||||
use App\Http\Responses\Api\Player\Challenges\ChallengeProgressionEntry;
|
||||
use App\Http\Responses\Api\Player\Challenges\GetChallengesEntry;
|
||||
use App\Models\Game\Challenge;
|
||||
use App\Models\Game\Matchmaking\Game;
|
||||
use App\Models\Game\PickedChallenge;
|
||||
use App\Models\Game\TimedChallenge;
|
||||
use App\Models\User\PlayerData;
|
||||
use App\Models\User\User;
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
use Illuminate\Database\UniqueConstraintViolationException;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Response;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\UnauthorizedException;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
|
||||
|
|
@ -26,9 +37,30 @@ class ChallengeController extends Controller
|
|||
*
|
||||
* @return false|string
|
||||
*/
|
||||
public function getChallenges()
|
||||
public function getChallenges(GetChallengesRequest $request)
|
||||
{
|
||||
return json_encode(['challenges' => []]);
|
||||
$user = $request->user;
|
||||
$timedChallenges = TimedChallenge::where('start_time', '<', Carbon::now())
|
||||
->where('end_time', '>', Carbon::now())
|
||||
->where('type', $request->type)
|
||||
->get();
|
||||
|
||||
$challenges = [];
|
||||
$timedChallenges->each(function (TimedChallenge $challenge) use (&$challenges, $user) {
|
||||
$challenges[] = new GetChallengesEntry(
|
||||
$challenge->id,
|
||||
$challenge->start_time,
|
||||
$challenge->end_time,
|
||||
$challenge->type,
|
||||
$challenge->completion_value,
|
||||
$challenge->faction,
|
||||
$challenge->blueprint_path,
|
||||
$challenge->rewards,
|
||||
$challenge->hasPlayerClaimed($user->playerData()->id),
|
||||
);
|
||||
});
|
||||
|
||||
return Response::json(['challenges' => $challenges]);
|
||||
}
|
||||
|
||||
public function getProgressionBatch(GetChallengeProgressionBatchRequest $request)
|
||||
|
|
@ -36,12 +68,23 @@ public function getProgressionBatch(GetChallengeProgressionBatchRequest $request
|
|||
$user = User::findOrFail($request->userId);
|
||||
$playerData = $user->playerData();
|
||||
|
||||
$timedChallengeIds = [];
|
||||
|
||||
foreach ($request->challengeIds as $index => $id) {
|
||||
if(Str::startsWith($id, GetChallengesEntry::ID_PREFIX)) {
|
||||
$timedChallengeIds[] = Str::remove(GetChallengesEntry::ID_PREFIX, $id);
|
||||
unset($request->challengeIds[$index]);
|
||||
}
|
||||
}
|
||||
|
||||
$challengeIdsToCheck = UuidHelper::convertFromHexToUuidCollecton($request->challengeIds, true);
|
||||
|
||||
/** @var Challenge[]|Collection $challengesToCheck */
|
||||
$challengesToCheck = Challenge::findMany($challengeIdsToCheck);
|
||||
/** @var PickedChallenge[]|Collection $pickedChallengesToCheck */
|
||||
$pickedChallengesToCheck = PickedChallenge::findMany($challengeIdsToCheck);
|
||||
/** @var TimedChallenge[]|Collection $timedChallengesToCheck */
|
||||
$timedChallengesToCheck = TimedChallenge::findMany($timedChallengeIds);
|
||||
|
||||
$response = new ChallengeProgressionBatchResponse();
|
||||
|
||||
|
|
@ -57,6 +100,20 @@ public function getProgressionBatch(GetChallengeProgressionBatchRequest $request
|
|||
$response->progressionBatch[] = $newEntry;
|
||||
}
|
||||
|
||||
foreach ($timedChallengesToCheck as $challenge) {
|
||||
$progress = $challenge->getProgressForPlayer($playerData->id);
|
||||
|
||||
$entry = new ChallengeProgressionEntry(
|
||||
GetChallengesEntry::ID_PREFIX . $challenge->id,
|
||||
$challenge->progress >= $challenge->completion_value,
|
||||
$progress,
|
||||
);
|
||||
|
||||
$entry->rewardsClaimed = $challenge->rewards;
|
||||
|
||||
$response->progressionBatch[] = $entry;
|
||||
}
|
||||
|
||||
foreach ($pickedChallengesToCheck as $challenge) {
|
||||
$response->progressionBatch[] = new ChallengeProgressionEntry(
|
||||
Uuid::fromString($challenge->id)->getHex()->toString(),
|
||||
|
|
@ -65,6 +122,8 @@ public function getProgressionBatch(GetChallengeProgressionBatchRequest $request
|
|||
);
|
||||
}
|
||||
|
||||
foreach ($challengesToCheck as $challenge) {}
|
||||
|
||||
return json_encode($response);
|
||||
}
|
||||
|
||||
|
|
@ -83,7 +142,11 @@ public function executeChallengeProgressionBatch(ExecuteChallengeProgressionBatc
|
|||
$processedChallenges = [];
|
||||
|
||||
foreach ($request->operations as $operation) {
|
||||
$challengeId = Uuid::fromString($operation['challengeId'])->toString();
|
||||
$challengeId = $operation['challengeId'];
|
||||
|
||||
if(!Str::startsWith($challengeId, GetChallengesEntry::ID_PREFIX)) {
|
||||
$challengeId = Uuid::fromString($operation['challengeId'])->toString();
|
||||
}
|
||||
|
||||
// Skip if we already processed this challenge because the completed ones are always first in the array.
|
||||
if(in_array($challengeId, $processedChallenges))
|
||||
|
|
@ -99,8 +162,13 @@ public function executeChallengeProgressionBatch(ExecuteChallengeProgressionBatc
|
|||
|
||||
protected function addProgressToChallenge(string $challengeId, int $newProgress, User $user): void
|
||||
{
|
||||
/** @var Challenge|null $foundChallenge */
|
||||
$foundChallenge = $user->playerData()->challenges()->find($challengeId);
|
||||
if(Str::startsWith($challengeId, GetChallengesEntry::ID_PREFIX)) {
|
||||
$foundChallenge = TimedChallenge::find(Str::remove(GetChallengesEntry::ID_PREFIX, $challengeId));
|
||||
}
|
||||
else {
|
||||
/** @var Challenge|null $foundChallenge */
|
||||
$foundChallenge = $user->playerData()->challenges()->find($challengeId);
|
||||
}
|
||||
|
||||
if($foundChallenge !== null) {
|
||||
$foundChallenge->playerData()->updateExistingPivot($user->playerData()->id, [
|
||||
|
|
@ -109,23 +177,51 @@ protected function addProgressToChallenge(string $challengeId, int $newProgress,
|
|||
return;
|
||||
}
|
||||
|
||||
/** @var PickedChallenge $foundChallenge */
|
||||
$foundChallenge = PickedChallenge::find($challengeId);
|
||||
if($foundChallenge === null)
|
||||
return;
|
||||
|
||||
$newProgress = $newProgress >= MetadataController::reducePickedChallengeCompletionValue($foundChallenge->asset_path, $foundChallenge->completion_value) ? $foundChallenge->completion_value : $newProgress;
|
||||
|
||||
$foundChallenge->progress = $newProgress;
|
||||
$foundChallenge->save();
|
||||
}
|
||||
|
||||
protected function setChallengeAsCompleted(string $challengeId, User $user)
|
||||
{
|
||||
/** @var Challenge|null $foundChallenge */
|
||||
$foundChallenge = $user->playerData()->challenges()->find($challengeId);
|
||||
$isTimed = false;
|
||||
// If the Challenge id starts with the Prefix, handle it as a timed challenge.
|
||||
if(Str::startsWith($challengeId, GetChallengesEntry::ID_PREFIX)) {
|
||||
$foundChallenge = TimedChallenge::find(Str::remove(GetChallengesEntry::ID_PREFIX, $challengeId));
|
||||
$isTimed = true;
|
||||
}
|
||||
else {
|
||||
/** @var Challenge|null $foundChallenge */
|
||||
$foundChallenge = $user->playerData()->challenges()->find($challengeId);
|
||||
}
|
||||
|
||||
if($foundChallenge !== null) {
|
||||
$foundChallenge->playerData()->updateExistingPivot($user->playerData()->id, [
|
||||
$pivotToEdit = [
|
||||
'progress' => $foundChallenge->completion_value,
|
||||
]);
|
||||
];
|
||||
|
||||
if($isTimed) {
|
||||
$playerData = $user->playerData();
|
||||
$hasClaimed = $foundChallenge->hasPlayerClaimed($playerData->id);
|
||||
|
||||
if(!$hasClaimed) {
|
||||
$rewardsToAdd = $foundChallenge->getRewards();
|
||||
|
||||
foreach($rewardsToAdd as $reward) {
|
||||
$this->addReward($reward, $playerData);
|
||||
}
|
||||
$playerData->save();
|
||||
$pivotToEdit['claimed'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$foundChallenge->playerData()->updateExistingPivot($user->playerData()->id, $pivotToEdit);
|
||||
$foundChallenge->save();
|
||||
return;
|
||||
}
|
||||
|
|
@ -137,4 +233,33 @@ protected function setChallengeAsCompleted(string $challengeId, User $user)
|
|||
$foundChallenge->progress = $foundChallenge->completion_value;
|
||||
$foundChallenge->save();
|
||||
}
|
||||
|
||||
protected function addReward(Reward $reward, PlayerData &$playerData): void
|
||||
{
|
||||
if ($reward->type === RewardType::Currency) {
|
||||
switch ($reward->id) {
|
||||
case 'CurrencyA':
|
||||
$playerData->currency_a += $reward->amount;
|
||||
break;
|
||||
case 'CurrencyB':
|
||||
$playerData->currency_b += $reward->amount;
|
||||
break;
|
||||
case 'CurrencyC':
|
||||
$playerData->currency_c += $reward->amount;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if ($reward->type === RewardType::Inventory) {
|
||||
$itemUuid = Uuid::fromString($reward->id)->toString();
|
||||
|
||||
try {
|
||||
// Since we can only have one occurrence of an item in the inventory, and an exception gets thrown when we try to add the same item twice
|
||||
$playerData->inventory()->attach($itemUuid);
|
||||
} catch (UniqueConstraintViolationException $e) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ public function deleteMultiple(Request $request) {
|
|||
$timestampsToDelete = [];
|
||||
foreach($messages as $message) {
|
||||
try {
|
||||
$timestampsToDelete[] = Carbon::createFromTimestampMs($message['received'])->toDateTimeString();
|
||||
$timestampsToDelete[] = Carbon::createFromTimestampMs($message['received'], config('app.timezone'))->toDateTimeString();
|
||||
} catch(\Exception $e) {
|
||||
$logger = AccessLogger::getSessionLogConfig();
|
||||
$logger->warning($request->method().' '.$request->getUri().': Something Went Wrong, Messagelist: '.json_encode($messages, JSON_PRETTY_PRINT));
|
||||
|
|
@ -112,7 +112,7 @@ public function markMessages(Request $request) {
|
|||
|
||||
foreach($messages as $message) {
|
||||
try {
|
||||
$timestampsToSet[] = Carbon::createFromTimestampMs($message['received'])->toDateTimeString();
|
||||
$timestampsToSet[] = Carbon::createFromTimestampMs($message['received'], config('app.timezone'))->toDateTimeString();
|
||||
$resultList[] = [
|
||||
'received' => $message['received'],
|
||||
'success' => true,
|
||||
|
|
@ -141,7 +141,7 @@ public function claimMessage(ClaimInboxMessageRequest $request)
|
|||
/** @var InboxMessage $message */
|
||||
$message = $user->inboxMessages()
|
||||
->where('user_id', '=', $user->id)
|
||||
->where('received', '=', Carbon::createFromTimestampMs($request->receivedTimestamp))
|
||||
->where('received', '=', Carbon::createFromTimestampMs($request->receivedTimestamp, config('app.timezone')))
|
||||
->first();
|
||||
|
||||
if($message === null)
|
||||
|
|
|
|||
|
|
@ -21,6 +21,48 @@
|
|||
|
||||
class MetadataController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Mapping from
|
||||
*/
|
||||
const PICKED_CHALLENGE_REDUCTION_MAPPING = [
|
||||
'/Game/Challenges/Progression/General/Challenge_Downing_Hunter.Challenge_Downing_Hunter' => 74.49,
|
||||
'/Game/Challenges/Progression/General/Challenge_Execution_Hunter.Challenge_Execution_Hunter' => 76.19,
|
||||
'/Game/Challenges/Progression/General/Challenge_Ressources_Runner.Challenge_Ressources_Runner' => 58.05,
|
||||
'/Game/Challenges/Progression/General/Challenge_Travel_Hunter.Challenge_Travel_Hunter' => 52.38,
|
||||
'/Game/Challenges/Progression/General/Challenge_Travel_Runner.Challenge_Travel_Runner' => 50.00,
|
||||
'/Game/Challenges/Progression/General/Challenge_Hacking_Hunter.Challenge_Hacking_Hunter' => 85.71,
|
||||
'/Game/Challenges/Progression/General/Challenge_Drones_Hunter.Challenge_Drones_Hunter' => 95.24,
|
||||
'/Game/Challenges/Progression/General/Challenge_TeamActions_Runner.Challenge_TeamActions_Runner' => 47.09,
|
||||
'/Game/Challenges/Progression/General/Challenge_HunterClose_Runner.Challenge_HunterClose_Runner' => 76.19,
|
||||
'/Game/Challenges/Progression/General/Challenge_Damage_Hunter.Challenge_Damage_Hunter' => 40.48,
|
||||
'/Game/Challenges/Progression/General/Challenge_ConstructDefeats_Runner.Challenge_ConstructDefeats_Runner' => 73.54,
|
||||
'/Game/Challenges/Progression/General/Challenge_Heal_Runner.Challenge_Heal_Runner' => 52.38,
|
||||
'/Game/Challenges/Progression/General/Challenge_RingOut_Hunter.Challenge_RingOut_Hunter' => 58.33,
|
||||
'/Game/Challenges/Progression/General/Challenge_Supercharge_Hunter.Challenge_Supercharge_Hunter' => 78.57,
|
||||
'/Game/Challenges/Progression/General/Challenge_TakeDamage_Runner.Challenge_TakeDamage_Runner' => 57.14,
|
||||
'/Game/Challenges/Progression/General/Challenge_Evade_Runner.Challenge_Evade_Runner' => 70.24,
|
||||
'/Game/Challenges/Progression/General/Challenge_Climb_Runner.Challenge_Climb_Runner' => 86.11,
|
||||
'/Game/Challenges/Challenge_Deliver_Runner.Challenge_Deliver_Runner' => 57.14,
|
||||
'/Game/Challenges/Progression/General/Challenge_Mark_Runner.Challenge_Mark_Runner' => 71.43,
|
||||
'/Game/Challenges/Progression/General/Challenge_Reveal_Hunter.Challenge_Reveal_Hunter' => 94.29,
|
||||
'/Game/Challenges/Progression/General/Challenge_HackCrates_Hunter.Challenge_HackCrates_Hunter' => 42.86,
|
||||
'/Game/Challenges/Progression/General/Challenge_SpendNPI_Runner.Challenge_SpendNPI_Runner' => 42.86,
|
||||
'/Game/Challenges/Progression/General/Challenge_CollectAmmo.Challenge_CollectAmmo' => 52.38,
|
||||
'/Game/Challenges/Progression/General/Challenge_CollectWeaponUpgrades_Runner.Challenge_CollectWeaponUpgrades_Runner' => 52.38,
|
||||
'/Game/Challenges/Progression/General/Challenge_CollectHealthCrates.Challenge_CollectHealthCrates' => 90.48,
|
||||
'/Game/Challenges/Progression/General/Challenge_DisableDrones_Runner.Challenge_DisableDrones_Runner' => 61.90,
|
||||
'/Game/Challenges/Challenge_DroneCharger_Hunter.Challenge_DroneCharger_Hunter' => 66.67,
|
||||
'/Game/Challenges/Progression/General/Challenge_Stomp_Hunter.Challenge_Stomp_Hunter' => 50.00,
|
||||
'/Game/Challenges/Progression/General/Challenge_Aim_Hunter.Challenge_Aim_Hunter' => 42.86,
|
||||
'/Game/Challenges/Progression/General/Challenge_DangerClose_Runner.Challenge_DangerClose_Runner' => 76.19,
|
||||
'/Game/Challenges/Progression/General/Challenge_SurviveAChase_Runner.Challenge_SurviveAChase_Runner' => 64.29,
|
||||
'/Game/Challenges/Progression/General/Challenge_AssistAChase_Runner.Challenge_AssistAChase_Runner' => 28.57,
|
||||
'/Game/Challenges/Progression/General/Challenge_Exit_Runner.Challenge_Exit_Runner' => 42.86,
|
||||
'/Game/Challenges/Progression/General/Challenge_BloodMode_Runner.Challenge_BloodMode_Runner' => 42.86,
|
||||
'/Game/Challenges/Progression/General/Challenge_LastMAnStanding_Hunter.Challenge_LastManStanding_Hunter' => 42.86,
|
||||
];
|
||||
|
||||
public function initOrGetGroups(InitOrGetGroupsRequest $request)
|
||||
{
|
||||
$response = new InitOrGetGroupsResponse();
|
||||
|
|
@ -56,6 +98,8 @@ public function initOrGetGroups(InitOrGetGroupsRequest $request)
|
|||
return json_encode($response);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function updateMetadataGroup(UpdateMetadataGroupRequest $request)
|
||||
{
|
||||
switch ($request->group) {
|
||||
|
|
@ -96,8 +140,17 @@ private function handleUpdateCharacterMetadata(UpdateMetadataGroupRequest &$requ
|
|||
$convertedIds = UuidHelper::convertFromHexToUuidCollecton($request->metadata['equippedWeapons'], true);
|
||||
$characterData->equippedWeapons()->sync($convertedIds);
|
||||
|
||||
$convertedIds = UuidHelper::convertFromHexToUuidCollecton($request->metadata['equippedBonuses'], true);
|
||||
$characterData->equippedBonuses()->sync($convertedIds);
|
||||
$characterConfig = $characterData->character->getCharacter()->getItemConfigClass();
|
||||
$defaultCompletedIds = [
|
||||
...$characterConfig::getDefaultEquippedBonuses(),
|
||||
...$characterConfig::getDefaultEquippedWeapons(),
|
||||
...$characterConfig::getDefaultEquipment(),
|
||||
...$characterConfig::getDefaultPowers(),
|
||||
...$characterConfig::getDefaultWeapons(),
|
||||
...$characterConfig::getDefaultEquippedPerks(),
|
||||
];
|
||||
|
||||
$defaultCompletedIds = UuidHelper::convertFromHexToUuidCollecton($defaultCompletedIds, true);
|
||||
|
||||
foreach ($request->metadata['pickedChallenges'] as $picked) {
|
||||
$itemId = Uuid::fromHexadecimal(new Hexadecimal($picked['itemId']));
|
||||
|
|
@ -109,14 +162,19 @@ private function handleUpdateCharacterMetadata(UpdateMetadataGroupRequest &$requ
|
|||
|
||||
foreach ($picked['list'] as $challenge) {
|
||||
$challengeId = Uuid::fromHexadecimal(new Hexadecimal($challenge['challengeId']));
|
||||
$completionValue = $challenge['challengeCompletionValue'];
|
||||
$assetPath = $challenge['challengeAsset'];
|
||||
$completionValue = $challenge['challengeCompletionValue'];
|
||||
|
||||
$newPicked = new PickedChallenge([
|
||||
$attributes = [
|
||||
'id' => $challengeId->toString(),
|
||||
'completion_value' => $completionValue,
|
||||
'asset_path' => $assetPath,
|
||||
]);
|
||||
];
|
||||
|
||||
if($defaultCompletedIds->has($itemId->toString()))
|
||||
$attributes['progress'] = $completionValue;
|
||||
|
||||
$newPicked = new PickedChallenge($attributes);
|
||||
|
||||
$newPicked->characterData()->associate($characterData);
|
||||
$newPicked->catalogItem()->associate($itemId->toString());
|
||||
|
|
@ -172,4 +230,20 @@ private function handleFactionMetadata(UpdateMetadataGroupRequest &$request): st
|
|||
throw new \Exception('Handle Update Faction Metadata not implemented yet');
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduces the Completion value of the given challenge.
|
||||
*
|
||||
* @param string $challengeBlueprint
|
||||
* @param string $originalAmount
|
||||
* @return int
|
||||
*/
|
||||
public static function reducePickedChallengeCompletionValue(
|
||||
string $challengeBlueprint,
|
||||
string $originalAmount,
|
||||
): int {
|
||||
if(isset(static::PICKED_CHALLENGE_REDUCTION_MAPPING[$challengeBlueprint]))
|
||||
return $originalAmount - (static::PICKED_CHALLENGE_REDUCTION_MAPPING[$challengeBlueprint] / 100 * $originalAmount);
|
||||
return $originalAmount;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -179,6 +179,7 @@ protected function resetCharacter(CharacterData &$characterData): void
|
|||
...$config::getDefaultEquippedPerks(),
|
||||
...$config::getDefaultPowers(),
|
||||
...$config::getDefaultEquippedWeapons(),
|
||||
...$config::getDefaultWeapons(),
|
||||
...$config::getDefaultEquippedBonuses(),
|
||||
], true);
|
||||
$inventory = $characterData->playerData->inventory();
|
||||
|
|
@ -186,7 +187,7 @@ protected function resetCharacter(CharacterData &$characterData): void
|
|||
// first detach all character items
|
||||
$inventory->detach($allItemsToRemove);
|
||||
//then attach the defaults again
|
||||
$inventory->attach([...$defaultItems, $config::getCharacterId()->toString()]);
|
||||
$inventory->syncWithoutDetaching([...$defaultItems, $config::getCharacterId()->toString()]);
|
||||
|
||||
// Remove signature challenges
|
||||
foreach ($allItemsToRemove as $item) {
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ public function store(Request $request)
|
|||
$filename = $file->getClientOriginalName();
|
||||
$filehash = str(hash_file('sha256', $file->getRealPath()))->upper();
|
||||
|
||||
$gameFile = GameFile::where('filename', $filename)->where('patchline', $request->input('patchline'))->first() ?? new GameFile;
|
||||
$gameFile = GameFile::where('filename', $filename)->where('patchline', $request->input('patchline'))->latest()->first() ?? new GameFile;
|
||||
|
||||
if ($gameFile->hash == $filehash) {
|
||||
$duplicateFiles[] = $gameFile->filename;
|
||||
|
|
@ -54,6 +54,11 @@ public function store(Request $request)
|
|||
}
|
||||
|
||||
if (isset($gameFile->id)) {
|
||||
$gameFile->action = 0;
|
||||
$gameFile->save();
|
||||
|
||||
$gameFile->child_id = $gameFile->id;
|
||||
$gameFile = $gameFile->replicate();
|
||||
$overwrittenFiles[] = $gameFile->filename;
|
||||
}
|
||||
|
||||
|
|
@ -61,13 +66,20 @@ public function store(Request $request)
|
|||
$gameFile->hash = $filehash;
|
||||
$gameFile->patchline = $request->input('patchline');
|
||||
|
||||
$gameFile->name = $request->input('game_mod_name')[$i];
|
||||
$gameFile->description = $request->input('game_mod_description')[$i];
|
||||
if (filled($request->input('game_mod_name'))) {
|
||||
$gameFile->name = $request->input('game_mod_name')[$i];
|
||||
}
|
||||
|
||||
if (filled($request->input('game_mod_description'))) {
|
||||
$gameFile->description = $request->input('game_mod_description')[$i];
|
||||
}
|
||||
|
||||
$gameFile->is_additional = $request->input('is_additional');
|
||||
|
||||
GameFile::getDisk()->putFileAs(strtolower($gameFile->patchline->name), $file, $gameFile->filename);
|
||||
$uploadedFiles[] = $gameFile->filename;
|
||||
|
||||
|
||||
$gameFile->game_path = $request->game_path[$i];
|
||||
$gameFile->action = $request->file_action[$i];
|
||||
$gameFile->save();
|
||||
|
|
@ -84,7 +96,7 @@ public function store(Request $request)
|
|||
}
|
||||
|
||||
if (count($duplicateFiles) > 0) {
|
||||
Session::flash('alert-warning', 'The following files already exist: <br>' . implode('<br>', $duplicateFiles));
|
||||
Session::flash('alert-warning', 'The following files with the same hash already exist: <br>' . implode('<br>', $duplicateFiles));
|
||||
//return response()->json(['message' => 'Only some files was uploaded successfully. The following files already exist: ' . implode(', ', $duplicateFiles)]);
|
||||
}
|
||||
|
||||
|
|
@ -100,12 +112,15 @@ public function store(Request $request)
|
|||
public function index(Request $request) : View {
|
||||
$patchline = Patchline::tryFrom($request->input('patchline')) ?? Patchline::LIVE;
|
||||
|
||||
$files = GameFile::latest()->where('patchline', $patchline)->where('is_additional', (bool)$request->input('additional_files'))->get();
|
||||
$allFiles = GameFile::where('patchline', $patchline)
|
||||
->where('is_additional', (bool)$request->input('additional_files'))
|
||||
->withFileHistory();
|
||||
|
||||
|
||||
return view('admin.tools.file-manager', [
|
||||
'patchline' => $patchline,
|
||||
'showAdditionalFiles' => (bool)$request->input('additional_files'),
|
||||
'files' => $files,
|
||||
'files' => $allFiles,
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ class LauncherMessageController extends AdminToolController
|
|||
{
|
||||
protected static string $name = 'Launcher Message';
|
||||
|
||||
protected static string $description = 'Set the Launcher message';
|
||||
protected static string $description = 'Set the Launcher Message';
|
||||
protected static string $iconComponent = 'icons.patch-exclamation';
|
||||
|
||||
protected static Permissions $neededPermission = Permissions::FILE_UPLOAD;
|
||||
|
|
@ -38,4 +38,4 @@ public function saveMessage(SaveLauncherMessageRequest $request) {
|
|||
|
||||
return back();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,12 @@
|
|||
use App\Http\Requests\Api\Admin\Tools\SaveCurrencyConfiguration;
|
||||
use App\Http\Requests\Api\Admin\Tools\SaveLauncherMessageRequest;
|
||||
use App\Http\Requests\Api\Admin\Tools\SaveMatchConfigurationRequest;
|
||||
use App\Http\Requests\Api\Admin\Tools\SaveMatchmakingConfigurationRequest;
|
||||
use App\Http\Requests\Api\Admin\Tools\SaveVersioningRequest;
|
||||
use App\Models\Admin\CurrencyMultipliers;
|
||||
use App\Models\Admin\ExperienceMultipliers;
|
||||
use App\Models\Admin\LauncherMessage;
|
||||
use App\Models\Admin\MatchmakingSettings;
|
||||
use App\Models\Admin\Versioning\CurrentCatalogVersion;
|
||||
use App\Models\Admin\Versioning\CurrentContentVersion;
|
||||
use App\Models\Admin\Versioning\CurrentGameVersion;
|
||||
|
|
@ -73,4 +75,20 @@ public function saveCurrency(SaveCurrencyConfiguration $request)
|
|||
return back();
|
||||
}
|
||||
|
||||
public function saveMatchmaking(SaveMatchmakingConfigurationRequest $request) {
|
||||
$matchmakingConfig = MatchmakingSettings::get();
|
||||
|
||||
try {
|
||||
$matchmakingConfig->matchWaitingTime = $request->matchmakingWaitingTime;
|
||||
$matchmakingConfig->save();
|
||||
|
||||
Session::flash('alert-success', 'Matchmaking configuration saved successfully.');
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
Session::flash('alert-error', 'Matchmaking configuration could not be saved, something went wrong: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -47,6 +47,14 @@ public function downloadLauncher()
|
|||
abort(404);
|
||||
}
|
||||
|
||||
public function patchNotes(): Factory|Application|View|\Illuminate\Contracts\Foundation\Application
|
||||
{
|
||||
static::setTitle('Deathgarden: Rebirth | Patch Notes');
|
||||
CompView::share('metaKeywords', ['Deathgarden', 'Rebirth', 'patch', 'patchnnotes', 'patch notes']);
|
||||
CompView::share('metaDescription', 'Stay up to date with all the changes, improvements, and updates in Deathgarden: Rebirth. Below is a complete archive of every patch since the mods release.');
|
||||
return view('web.patch-notes');
|
||||
}
|
||||
|
||||
public function howToPlay(): Factory|Application|View|\Illuminate\Contracts\Foundation\Application
|
||||
{
|
||||
static::setTitle('Deathgarden: Rebirth | How to Play');
|
||||
|
|
|
|||
2
dist/app/Http/Kernel.php
vendored
2
dist/app/Http/Kernel.php
vendored
|
|
@ -3,7 +3,6 @@
|
|||
namespace App\Http;
|
||||
|
||||
use App\Http\Middleware\AccessLogger;
|
||||
use App\Http\Middleware\HandleInertiaRequests;
|
||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||
|
||||
class Kernel extends HttpKernel
|
||||
|
|
@ -39,7 +38,6 @@ class Kernel extends HttpKernel
|
|||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
HandleInertiaRequests::class,
|
||||
],
|
||||
|
||||
'api' => [
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Middleware;
|
||||
|
||||
class HandleInertiaRequests extends Middleware
|
||||
{
|
||||
/**
|
||||
* The root template that's loaded on the first page visit.
|
||||
*
|
||||
* @see https://inertiajs.com/server-side-setup#root-template
|
||||
* @var string
|
||||
*/
|
||||
protected $rootView = 'app';
|
||||
|
||||
/**
|
||||
* Determines the current asset version.
|
||||
*
|
||||
* @see https://inertiajs.com/asset-versioning
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return string|null
|
||||
*/
|
||||
public function version(Request $request): ?string
|
||||
{
|
||||
return parent::version($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the props that are shared by default.
|
||||
*
|
||||
* @see https://inertiajs.com/shared-data
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function share(Request $request): array
|
||||
{
|
||||
return array_merge(parent::share($request), [
|
||||
//
|
||||
]);
|
||||
}
|
||||
}
|
||||
21
dist/app/Http/Requests/Api/Admin/Tools/SaveMatchmakingConfigurationRequest.php
vendored
Normal file
21
dist/app/Http/Requests/Api/Admin/Tools/SaveMatchmakingConfigurationRequest.php
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Api\Admin\Tools;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class SaveMatchmakingConfigurationRequest extends FormRequest
|
||||
{
|
||||
public int $matchmakingWaitingTime;
|
||||
|
||||
public function rules(): array {
|
||||
return [
|
||||
'matchmakingWaitingTime' => ['required', 'integer'],
|
||||
];
|
||||
}
|
||||
|
||||
protected function passedValidation()
|
||||
{
|
||||
$this->matchmakingWaitingTime = (int)$this->input('matchmakingWaitingTime');
|
||||
}
|
||||
}
|
||||
42
dist/app/Http/Requests/Api/Player/GetChallengesRequest.php
vendored
Normal file
42
dist/app/Http/Requests/Api/Player/GetChallengesRequest.php
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Api\Player;
|
||||
|
||||
use App\Enums\Game\ChallengeType;
|
||||
use App\Models\User\User;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class GetChallengesRequest extends FormRequest
|
||||
{
|
||||
public User $user;
|
||||
|
||||
public ChallengeType $type;
|
||||
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return \Auth::check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'data.userId' => 'required|exists:users,id',
|
||||
'data.challengeType' => ['required', Rule::enum(ChallengeType::class)],
|
||||
];
|
||||
}
|
||||
|
||||
public function passedValidation(): void
|
||||
{
|
||||
$this->user = User::find($this->input('data.userId'));
|
||||
$this->type = ChallengeType::tryFrom($this->input('data.challengeType'));
|
||||
}
|
||||
}
|
||||
56
dist/app/Http/Responses/Api/Player/Challenges/GetChallengesEntry.php
vendored
Normal file
56
dist/app/Http/Responses/Api/Player/Challenges/GetChallengesEntry.php
vendored
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Responses\Api\Player\Challenges;
|
||||
|
||||
use App\Enums\Game\ChallengeType;
|
||||
use App\Enums\Game\Faction;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class GetChallengesEntry implements \JsonSerializable
|
||||
{
|
||||
const ID_PREFIX = 'Timed:';
|
||||
|
||||
public function __construct(
|
||||
public int $id,
|
||||
public Carbon $startTime,
|
||||
public Carbon $endTime,
|
||||
public ChallengeType $type,
|
||||
public int $completionValue,
|
||||
public Faction $faction,
|
||||
public string $challengeBlueprint,
|
||||
public array $rewards,
|
||||
public bool $claimed,
|
||||
)
|
||||
{}
|
||||
|
||||
public function getChallengeId(): string {
|
||||
return static::ID_PREFIX . $this->id;
|
||||
}
|
||||
|
||||
public function jsonSerialize(): mixed
|
||||
{
|
||||
$json = [
|
||||
'lifetime' =>
|
||||
[
|
||||
'creationTime' => $this->startTime->toIso8601ZuluString(),
|
||||
'expirationTime' => $this->endTime->toIso8601ZuluString(),
|
||||
],
|
||||
'challengeType' => $this->type,
|
||||
'challengeId' => $this->getChallengeId(),
|
||||
'challengeCompletionValue' => $this->completionValue,
|
||||
'faction' => $this->faction,
|
||||
'challengeBlueprint' => $this->challengeBlueprint,
|
||||
];
|
||||
|
||||
$rewards = [];
|
||||
foreach ($this->rewards as &$reward) {
|
||||
$reward['claimed'] = $this->claimed;
|
||||
$reward['weight'] = 100;
|
||||
$rewards[] = $reward;
|
||||
}
|
||||
$json['rewards'] = $rewards;
|
||||
|
||||
return $json;
|
||||
}
|
||||
}
|
||||
|
|
@ -78,7 +78,9 @@ public function addCharacterMetadataGroup(Characters $character, User $user): vo
|
|||
$newGroup->equippedPerks = UuidHelper::convertFromUuidToHexCollection($characterData->equippedPerks()->allRelatedIds())->toArray();
|
||||
$newGroup->equippedWeapons = UuidHelper::convertFromUuidToHexCollection($characterData->equippedWeapons()->allRelatedIds())->toArray();
|
||||
$newGroup->equipment = UuidHelper::convertFromUuidToHexCollection($characterData->equipment()->allRelatedIds())->toArray();
|
||||
$newGroup->equippedBonuses = UuidHelper::convertFromUuidToHexCollection($characterData->equippedBonuses()->allRelatedIds())->toArray();
|
||||
|
||||
// Since players cannot change their equipped powers or passives(bonuses), we can just read them from the config.
|
||||
$newGroup->equippedBonuses = $itemConfigClass::getDefaultEquippedBonuses();
|
||||
$newGroup->equippedPowers = $itemConfigClass::getDefaultPowers();
|
||||
$newGroup->prestigeLevel = $characterData->prestige_level;
|
||||
|
||||
|
|
|
|||
22
dist/app/Models/Admin/Archive/ArchivedGame.php
vendored
22
dist/app/Models/Admin/Archive/ArchivedGame.php
vendored
|
|
@ -2,17 +2,23 @@
|
|||
|
||||
namespace App\Models\Admin\Archive;
|
||||
|
||||
use App\Classes\Frontend\ChatMessage;
|
||||
use App\Enums\Game\Faction;
|
||||
use Illuminate\Database\Eloquent\Concerns\HasUuids;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
/**
|
||||
* @mixin IdeHelperArchivedGame
|
||||
*/
|
||||
class ArchivedGame extends Model
|
||||
{
|
||||
use HasUuids;
|
||||
|
||||
protected $casts = [
|
||||
'dominant_faction' => Faction::class,
|
||||
'chat_messages' => 'array',
|
||||
];
|
||||
|
||||
public function archivedPlayerProgressions(): HasMany
|
||||
|
|
@ -24,5 +30,21 @@ public static function archivedGameExists(string $matchId) {
|
|||
return ArchivedGame::where('id', '=', $matchId)->exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ChatMessage[]
|
||||
*/
|
||||
public function getChatMessages(): array {
|
||||
$result = [];
|
||||
|
||||
foreach ($this->chat_messages as $message) {
|
||||
$result[] = new ChatMessage(
|
||||
$message['gameId'],
|
||||
$message['userId'],
|
||||
Carbon::parse($message['messageTime']),
|
||||
$message['message'],
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
22
dist/app/Models/Admin/MatchmakingSettings.php
vendored
Normal file
22
dist/app/Models/Admin/MatchmakingSettings.php
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models\Admin;
|
||||
|
||||
use App\Models\AbstractFileBasedModel;
|
||||
|
||||
class MatchmakingSettings extends AbstractFileBasedModel
|
||||
{
|
||||
const FILE_NAME = 'matchmakingSettings';
|
||||
|
||||
const CACHE_DURATION = 86400;
|
||||
|
||||
/**
|
||||
* How long the matchmaking should wait when only one 1v4 or 1v5 could be made before actually making it.
|
||||
*/
|
||||
public int $matchWaitingTime = 10;
|
||||
|
||||
protected static function getDefault(): ?static
|
||||
{
|
||||
return new static();
|
||||
}
|
||||
}
|
||||
20
dist/app/Models/Game/CharacterData.php
vendored
20
dist/app/Models/Game/CharacterData.php
vendored
|
|
@ -49,11 +49,6 @@ public function equipment(): BelongsToMany
|
|||
return $this->belongsToMany(CatalogItem::class,'character_data_equipment');
|
||||
}
|
||||
|
||||
public function equippedBonuses(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(CatalogItem::class,'character_data_equipped_bonuses');
|
||||
}
|
||||
|
||||
public function equippedPerks(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(CatalogItem::class,'character_data_equipped_perks');
|
||||
|
|
@ -133,10 +128,6 @@ public function validateEquippedItems(): void
|
|||
$equippedEquipment = $this->equipment()->allRelatedIds();
|
||||
if($equippedEquipment->count() === 0)
|
||||
$this->resetEquipment($itemConfigClass);
|
||||
|
||||
$equippedBonuses = $this->equippedBonuses()->allRelatedIds();
|
||||
if($equippedBonuses->count() === 0)
|
||||
$this->resetEquippedBonuses($itemConfigClass);
|
||||
}
|
||||
|
||||
protected function resetEquippedPerks(string|CharacterItemConfig $itemConfigClass): void
|
||||
|
|
@ -172,17 +163,6 @@ protected function resetEquipment(string|CharacterItemConfig $itemConfigClass):
|
|||
static::getResetItemsLogger()->warning(sprintf('User %s(%s) had unallowed Equipment Equipped', $user->id, $user->last_known_username));
|
||||
}
|
||||
|
||||
protected function resetEquippedBonuses(string|CharacterItemConfig $itemConfigClass): void
|
||||
{
|
||||
// Remove all equipped Weapons and reset to default config
|
||||
$this->equippedBonuses()->detach();
|
||||
$defaultBonusIds = UuidHelper::convertFromHexToUuidCollecton($itemConfigClass::getDefaultEquippedBonuses());
|
||||
$this->equippedBonuses()->attach($defaultBonusIds);
|
||||
|
||||
$user = Auth::user();
|
||||
static::getResetItemsLogger()->warning(sprintf('User %s(%s) had unallowed Bonuses Equipped', $user->id, $user->last_known_username));
|
||||
}
|
||||
|
||||
protected static function getResetItemsLogger(): LoggerInterface
|
||||
{
|
||||
if(static::$resetItemsLogger === null) {
|
||||
|
|
|
|||
4
dist/app/Models/Game/Matchmaking/Game.php
vendored
4
dist/app/Models/Game/Matchmaking/Game.php
vendored
|
|
@ -8,6 +8,7 @@
|
|||
use App\Enums\Game\Faction;
|
||||
use App\Enums\Game\Matchmaking\MatchmakingSide;
|
||||
use App\Enums\Game\Matchmaking\MatchStatus;
|
||||
use App\Http\Controllers\Api\ModerationController;
|
||||
use App\Http\Requests\Api\Matchmaking\PlayerEndOfMatchRequest;
|
||||
use App\Models\Admin\Archive\ArchivedGame;
|
||||
use App\Models\Admin\Archive\ArchivedPlayerProgression;
|
||||
|
|
@ -107,6 +108,9 @@ public function archiveGame(Faction $dominantFaction): void
|
|||
$archived = new ArchivedGame();
|
||||
$archived->id = $this->id;
|
||||
$archived->dominant_faction = $dominantFaction;
|
||||
|
||||
$archived->chat_messages = Cache::get(ModerationController::CHAT_CACHE_KEY . $this->id, []);
|
||||
|
||||
$archived->save();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,8 +44,24 @@ public static function getAvailableMatchConfigs(int $runnerCount, int $hunterCou
|
|||
->get();
|
||||
}
|
||||
|
||||
public static function selectRandomConfigByWeight(Collection &$collection): MatchConfiguration|null
|
||||
public static function selectMatchConfig(Collection &$collection, int $runnerCount, int $hunterCount): MatchConfiguration|null
|
||||
{
|
||||
$filteredConfigs = new Collection();
|
||||
|
||||
if ($hunterCount === 1 && $runnerCount >= 6){
|
||||
$filteredConfigs = $collection->filter(function (MatchConfiguration $config) use ($runnerCount, $hunterCount) {
|
||||
return $config->runners >= 6 && $config->hunters === $hunterCount;
|
||||
});
|
||||
}
|
||||
else if ($hunterCount === 1 && $runnerCount >= 4){
|
||||
$filteredConfigs = $collection->filter(function (MatchConfiguration $config) use ($runnerCount, $hunterCount) {
|
||||
return $config->runners === $runnerCount && $config->hunters === $hunterCount;
|
||||
});
|
||||
}
|
||||
|
||||
if ($filteredConfigs->isNotEmpty())
|
||||
$collection = $filteredConfigs;
|
||||
|
||||
$weightSum = $collection->sum('weight');
|
||||
$random = random_int(1, $weightSum);
|
||||
$selectWalk = 0;
|
||||
|
|
|
|||
10
dist/app/Models/Game/QuitterState.php
vendored
10
dist/app/Models/Game/QuitterState.php
vendored
|
|
@ -117,7 +117,7 @@ public static function getReward(int $stayMatchStreak): array {
|
|||
return [
|
||||
new Reward(
|
||||
RewardType::Currency,
|
||||
50,
|
||||
150,
|
||||
'CurrencyA',
|
||||
),
|
||||
];
|
||||
|
|
@ -126,7 +126,7 @@ public static function getReward(int $stayMatchStreak): array {
|
|||
return [
|
||||
new Reward(
|
||||
RewardType::Currency,
|
||||
100,
|
||||
300,
|
||||
'CurrencyA',
|
||||
),
|
||||
new Reward(
|
||||
|
|
@ -145,7 +145,7 @@ public static function getReward(int $stayMatchStreak): array {
|
|||
return [
|
||||
new Reward(
|
||||
RewardType::Currency,
|
||||
150,
|
||||
450,
|
||||
'CurrencyA',
|
||||
),
|
||||
new Reward(
|
||||
|
|
@ -164,7 +164,7 @@ public static function getReward(int $stayMatchStreak): array {
|
|||
return [
|
||||
new Reward(
|
||||
RewardType::Currency,
|
||||
200,
|
||||
600,
|
||||
'CurrencyA',
|
||||
),
|
||||
new Reward(
|
||||
|
|
@ -183,7 +183,7 @@ public static function getReward(int $stayMatchStreak): array {
|
|||
return [
|
||||
new Reward(
|
||||
RewardType::Currency,
|
||||
250,
|
||||
750,
|
||||
'CurrencyA',
|
||||
),
|
||||
new Reward(
|
||||
|
|
|
|||
78
dist/app/Models/Game/TimedChallenge.php
vendored
Normal file
78
dist/app/Models/Game/TimedChallenge.php
vendored
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models\Game;
|
||||
|
||||
use App\Enums\Game\ChallengeType;
|
||||
use App\Enums\Game\Faction;
|
||||
use App\Enums\Game\RewardType;
|
||||
use App\Http\Responses\Api\General\Reward;
|
||||
use App\Models\User\PlayerData;
|
||||
use Carbon\Carbon;
|
||||
use Eloquent;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
|
||||
/**
|
||||
* @mixin IdeHelperTimedChallenge
|
||||
*/
|
||||
class TimedChallenge extends Model
|
||||
{
|
||||
protected $casts = [
|
||||
'type' => ChallengeType::class,
|
||||
'faction' => Faction::class,
|
||||
'start_time' => 'datetime',
|
||||
'end_time' => 'datetime',
|
||||
'rewards' => 'array',
|
||||
];
|
||||
|
||||
public function getProgressForPlayer(int $playerDataId): int
|
||||
{
|
||||
$foundProgress = $this->playerData()->where('id', '=', $playerDataId)->first();
|
||||
|
||||
if ($foundProgress !== null)
|
||||
return $foundProgress->pivot->progress;
|
||||
|
||||
// We create challange relation and just return 0 since you cannot have progress for the challenge we just linked.
|
||||
$this->playerData()->attach($playerDataId);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function hasPlayerClaimed(int $playerDataId): bool {
|
||||
$foundPlayerData = $this->playerData()->where('id', '=', $playerDataId)->first();
|
||||
|
||||
if ($foundPlayerData !== null)
|
||||
return $foundPlayerData->pivot->claimed;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Reward[]
|
||||
*/
|
||||
public function getRewards(): array {
|
||||
if ($this->rewards === null)
|
||||
return [];
|
||||
|
||||
$result = [];
|
||||
foreach ($this->rewards as $reward) {
|
||||
$result[] = new Reward(
|
||||
RewardType::tryFrom($reward['type']),
|
||||
$reward['amount'],
|
||||
$reward['id'],
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function playerData(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(PlayerData::class)->withPivot(['progress', 'claimed']);
|
||||
}
|
||||
|
||||
public static function currentChallenges(): Eloquent|Builder {
|
||||
return static::where('start_time', '>', Carbon::now())
|
||||
->where('end_time', '<', Carbon::now());
|
||||
}
|
||||
}
|
||||
45
dist/app/Models/GameFile.php
vendored
45
dist/app/Models/GameFile.php
vendored
|
|
@ -4,8 +4,10 @@
|
|||
|
||||
use App\Enums\Launcher\FileAction;
|
||||
use App\Enums\Launcher\Patchline;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Filesystem\FilesystemAdapter;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
|
|
@ -35,7 +37,7 @@ protected static function booted()
|
|||
});
|
||||
}
|
||||
|
||||
public static function getDisk():FileSystemAdapter {
|
||||
public static function getDisk(): FileSystemAdapter {
|
||||
return static::$disk ?? static::$disk = Storage::disk('patches');
|
||||
}
|
||||
|
||||
|
|
@ -54,4 +56,45 @@ public function fileExists(): bool
|
|||
public function getFileSize(): int {
|
||||
return static::getDisk()->size($this->getDiskPath());
|
||||
}
|
||||
|
||||
public function child(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(GameFile::class);
|
||||
}
|
||||
|
||||
public function getTopParent(): GameFile
|
||||
{
|
||||
$current = $this;
|
||||
while ($current->child) {
|
||||
$current = $current->child;
|
||||
}
|
||||
return $current;
|
||||
}
|
||||
|
||||
public function scopeWithFileHistory($query): Collection
|
||||
{
|
||||
return $query->latest()->get()->pipe(function ($allFiles) {
|
||||
$filesById = $allFiles->keyBy('id');
|
||||
|
||||
// Find files that are not referenced as child_id (these are the latest in their chains)
|
||||
$referencedIds = $allFiles->pluck('child_id')->filter();
|
||||
$latestFiles = $allFiles->whereNotIn('id', $referencedIds);
|
||||
|
||||
// Build complete history chains for each latest file
|
||||
return $latestFiles->map(function ($latestFile) use ($filesById) {
|
||||
$history = collect();
|
||||
|
||||
// Walk backwards through the chain to collect all history
|
||||
$currentId = $latestFile->child_id;
|
||||
while ($currentId && isset($filesById[$currentId])) {
|
||||
$historyFile = $filesById[$currentId];
|
||||
$history->push($historyFile);
|
||||
$currentId = $historyFile->child_id;
|
||||
}
|
||||
|
||||
$latestFile->children = $history;
|
||||
return $latestFile;
|
||||
})->sortByDesc('updated_at');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
32
dist/app/Models/User/PlayerData.php
vendored
32
dist/app/Models/User/PlayerData.php
vendored
|
|
@ -12,6 +12,8 @@
|
|||
use App\Models\Game\Challenge;
|
||||
use App\Models\Game\CharacterData;
|
||||
use App\Models\Game\QuitterState;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use App\Models\Game\TimedChallenge;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
|
|
@ -36,7 +38,7 @@ class PlayerData extends Model
|
|||
'currency_b' => 500,
|
||||
'currency_c' => 500,
|
||||
'last_faction' => Faction::Runner,
|
||||
'last_hunter' => Hunter::Inquisitor,
|
||||
'last_hunter' => Hunter::Mass,
|
||||
'last_runner' => Runner::Smoke,
|
||||
'readout_version' => 1,
|
||||
'runner_faction_level' => 1,
|
||||
|
|
@ -53,6 +55,8 @@ class PlayerData extends Model
|
|||
'has_played_dg_1' => 'boolean',
|
||||
];
|
||||
|
||||
const CURRENCY_CAP = 50000;
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::created(function (PlayerData $playerData) {
|
||||
|
|
@ -66,6 +70,7 @@ protected static function booted(): void
|
|||
...$configClass::getDefaultEquippedWeapons(),
|
||||
...$configClass::getDefaultEquipment(),
|
||||
...$configClass::getDefaultPowers(),
|
||||
...$configClass::getDefaultWeapons(),
|
||||
...$configClass::getDefaultEquippedPerks(),
|
||||
];
|
||||
|
||||
|
|
@ -88,6 +93,7 @@ protected static function booted(): void
|
|||
...$configClass::getDefaultEquippedWeapons(),
|
||||
...$configClass::getDefaultEquipment(),
|
||||
...$configClass::getDefaultPowers(),
|
||||
...$configClass::getDefaultWeapons(),
|
||||
...$configClass::getDefaultEquippedPerks(),
|
||||
];
|
||||
|
||||
|
|
@ -108,7 +114,7 @@ protected static function booted(): void
|
|||
Characters::Smoke->value,
|
||||
Characters::Ghost->value,
|
||||
Characters::Sawbones->value,
|
||||
Characters::Inquisitor->value,
|
||||
Characters::Mass->value,
|
||||
]
|
||||
]);
|
||||
});
|
||||
|
|
@ -143,6 +149,10 @@ public function challenges(): BelongsToMany
|
|||
return $this->belongsToMany(Challenge::class)->withPivot(['progress']);
|
||||
}
|
||||
|
||||
public function timedChallenges(): BelongsToMany {
|
||||
return $this->belongsToMany(TimedChallenge::class)->withPivot(['progress', 'claimed']);
|
||||
}
|
||||
|
||||
public function quitterState(): HasOne
|
||||
{
|
||||
return $this->hasOne(QuitterState::class);
|
||||
|
|
@ -192,4 +202,22 @@ public static function getRemainingFactionExperience(int $level): int
|
|||
return 4;
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function currencyA(): Attribute {
|
||||
return Attribute::make(
|
||||
set: fn (int $value) => min($value, static::CURRENCY_CAP),
|
||||
);
|
||||
}
|
||||
|
||||
public function currencyB(): Attribute {
|
||||
return Attribute::make(
|
||||
set: fn (int $value) => min($value, static::CURRENCY_CAP),
|
||||
);
|
||||
}
|
||||
|
||||
public function currencyC(): Attribute {
|
||||
return Attribute::make(
|
||||
set: fn (int $value) => min($value, static::CURRENCY_CAP),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
29
dist/app/View/Components/Admin/ChatHistory.php
vendored
Normal file
29
dist/app/View/Components/Admin/ChatHistory.php
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace App\View\Components\Admin;
|
||||
|
||||
use App\Classes\Frontend\ChatMessage;
|
||||
use Closure;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\View\Component;
|
||||
|
||||
class ChatHistory extends Component
|
||||
{
|
||||
/**
|
||||
* @param ChatMessage[] $messages
|
||||
*/
|
||||
public function __construct(
|
||||
public array $messages
|
||||
)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*/
|
||||
public function render(): View|Closure|string
|
||||
{
|
||||
return view('components.admin.chat-history');
|
||||
}
|
||||
}
|
||||
33
dist/app/View/Components/Admin/MatchInfo.php
vendored
Normal file
33
dist/app/View/Components/Admin/MatchInfo.php
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace App\View\Components\Admin;
|
||||
|
||||
use App\Models\Admin\Archive\ArchivedGame;
|
||||
use App\Models\Admin\Archive\ArchivedPlayerProgression;
|
||||
use Closure;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\View\Component;
|
||||
|
||||
class MatchInfo extends Component
|
||||
{
|
||||
public Collection $players;
|
||||
|
||||
/**
|
||||
* Create a new component instance.
|
||||
*/
|
||||
public function __construct(
|
||||
public ArchivedGame $game,
|
||||
)
|
||||
{
|
||||
$this->players = ArchivedPlayerProgression::whereArchivedGameId($game->id)->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*/
|
||||
public function render(): View|Closure|string
|
||||
{
|
||||
return view('components.admin.match-info');
|
||||
}
|
||||
}
|
||||
6
dist/composer.json
vendored
6
dist/composer.json
vendored
|
|
@ -8,8 +8,7 @@
|
|||
"php": "^8.2",
|
||||
"consoletvs/profanity": "^3.5",
|
||||
"guzzlehttp/guzzle": "^7.2",
|
||||
"inertiajs/inertia-laravel": "^0.6.11",
|
||||
"laravel/framework": "^10.10",
|
||||
"laravel/framework": "^11.0",
|
||||
"laravel/octane": "^2.4",
|
||||
"laravel/socialite": "^5.12",
|
||||
"laravel/tinker": "^2.8",
|
||||
|
|
@ -19,12 +18,11 @@
|
|||
"spatie/laravel-permission": "^6.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"barryvdh/laravel-ide-helper": "^2.14",
|
||||
"barryvdh/laravel-ide-helper": "^3.2",
|
||||
"fakerphp/faker": "^1.9.1",
|
||||
"laravel/pint": "^1.0",
|
||||
"laravel/sail": "^1.18",
|
||||
"mockery/mockery": "^1.4.4",
|
||||
"nunomaduro/collision": "^7.0",
|
||||
"phpunit/phpunit": "^10.1",
|
||||
"spatie/laravel-ignition": "^2.0"
|
||||
},
|
||||
|
|
|
|||
2249
dist/composer.lock
generated
vendored
2249
dist/composer.lock
generated
vendored
File diff suppressed because it is too large
Load Diff
6
dist/config/filesystems.php
vendored
6
dist/config/filesystems.php
vendored
|
|
@ -44,6 +44,12 @@
|
|||
'throw' => false,
|
||||
],
|
||||
|
||||
'logs' => [
|
||||
'driver' => 'local',
|
||||
'root' => storage_path('logs'),
|
||||
'throw' => false,
|
||||
],
|
||||
|
||||
'patches' => [
|
||||
'driver' => 'local',
|
||||
'root' => storage_path('app/patches'),
|
||||
|
|
|
|||
9
dist/config/logging.php
vendored
9
dist/config/logging.php
vendored
|
|
@ -59,7 +59,7 @@
|
|||
],
|
||||
|
||||
'single' => [
|
||||
'driver' => 'single',
|
||||
'driver' => 'daily',
|
||||
'path' => storage_path('logs/laravel.log'),
|
||||
'level' => env('LOG_LEVEL', 'debug'),
|
||||
'replace_placeholders' => true,
|
||||
|
|
@ -135,6 +135,13 @@
|
|||
'replace_placeholders' => true,
|
||||
],
|
||||
|
||||
'challengeCreation' => [
|
||||
'driver' => 'single',
|
||||
'path' => storage_path('logs/challengeCreation.log'),
|
||||
'level' => 'info',
|
||||
'replace_placeholders' => true,
|
||||
],
|
||||
|
||||
'daily' => [
|
||||
'driver' => 'daily',
|
||||
'path' => storage_path('logs/laravel.log'),
|
||||
|
|
|
|||
2
dist/config/session.php
vendored
2
dist/config/session.php
vendored
|
|
@ -31,7 +31,7 @@
|
|||
|
|
||||
*/
|
||||
|
||||
'lifetime' => env('SESSION_LIFETIME', 120),
|
||||
'lifetime' => (int)env('SESSION_LIFETIME', 120),
|
||||
|
||||
'expire_on_close' => false,
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,6 @@ public function up(): void
|
|||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('catalog_item_challenges');
|
||||
Schema::dropIfExists('catalog_item_challenge');
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -11,8 +11,19 @@
|
|||
*/
|
||||
public function up(): void
|
||||
{
|
||||
if (Schema::hasIndex('game_files', ['name', 'hash', 'version'])) {
|
||||
Schema::table('game_files', function (Blueprint $table) {
|
||||
$table->dropUnique(['name', 'hash', 'version']);
|
||||
});
|
||||
}
|
||||
|
||||
//Schema doesn't support tinyint
|
||||
DB::statement("ALTER TABLE `game_files` CHANGE `version` `patchline` TINYINT UNSIGNED NOT NULL DEFAULT '1';");
|
||||
|
||||
|
||||
Schema::table('game_files', function (Blueprint $table) {
|
||||
$table->unique(['name', 'hash', 'patchline']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -20,11 +31,19 @@ public function up(): void
|
|||
*/
|
||||
public function down(): void
|
||||
{
|
||||
if (Schema::hasIndex('game_files', ['name', 'hash', 'patchline'])) {
|
||||
Schema::table('game_files', function (Blueprint $table) {
|
||||
$table->dropUnique(['name', 'hash', 'patchline']);
|
||||
});
|
||||
}
|
||||
Schema::table('game_files', function (Blueprint $table) {
|
||||
$table->integer('patchline')->default(1)->change();
|
||||
});
|
||||
Schema::table('game_files', function (Blueprint $table) {
|
||||
$table->renameColumn('patchline', 'version');
|
||||
});
|
||||
Schema::table('game_files', function (Blueprint $table) {
|
||||
$table->unique(['name', 'hash', 'version']);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
|||
28
dist/database/migrations/2024_09_21_203649_add_chat_messages_to_archived_game.php
vendored
Normal file
28
dist/database/migrations/2024_09_21_203649_add_chat_messages_to_archived_game.php
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('archived_games', function (Blueprint $table) {
|
||||
$table->json('chat_messages')->after('dominant_faction');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('archived_games', function (Blueprint $table) {
|
||||
$table->dropColumn('chat_messages');
|
||||
});
|
||||
}
|
||||
};
|
||||
28
dist/database/migrations/2024_10_03_194557_add_match_id_to_bad_chat_message.php
vendored
Normal file
28
dist/database/migrations/2024_10_03_194557_add_match_id_to_bad_chat_message.php
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('bad_chat_messages', function (Blueprint $table) {
|
||||
$table->uuid('match_id')->after('id')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('bad_chat_messages', function (Blueprint $table) {
|
||||
$table->dropColumn('match_id');
|
||||
});
|
||||
}
|
||||
};
|
||||
29
dist/database/migrations/2024_10_19_232253_remove_equipped_bonuses_table.php
vendored
Normal file
29
dist/database/migrations/2024_10_19_232253_remove_equipped_bonuses_table.php
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::dropIfExists('character_data_equipped_bonuses');
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::create('character_data_equipped_bonuses', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('character_data_id')->constrained('character_data')->cascadeOnDelete()->cascadeOnUpdate();
|
||||
$table->foreignUuid('catalog_item_id')->constrained()->cascadeOnDelete()->cascadeOnDelete();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -14,11 +14,11 @@ public function up(): void
|
|||
//Schema doesn't support tinyint
|
||||
DB::statement("ALTER TABLE `game_files` ADD COLUMN `is_additional` TINYINT UNSIGNED NOT NULL DEFAULT '0' AFTER `action`;");
|
||||
|
||||
if (Schema::hasIndex('game_files', ['name', 'hash', 'version'])) {
|
||||
if (Schema::hasIndex('game_files', ['name', 'hash', 'patchline'])) {
|
||||
Schema::table('game_files', function (Blueprint $table) {
|
||||
$table->dropUnique(['name', 'hash', 'version']);
|
||||
$table->dropUnique(['name', 'hash', 'patchline']);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Schema::table('game_files', function (Blueprint $table) {
|
||||
$table->renameColumn('name', 'filename');
|
||||
|
|
|
|||
36
dist/database/migrations/2024_12_03_201112_create_timed_challenges_table.php
vendored
Normal file
36
dist/database/migrations/2024_12_03_201112_create_timed_challenges_table.php
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
use App\Enums\Game\ChallengeType;
|
||||
use App\Enums\Game\Faction;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('timed_challenges', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->enum('type', array_column(ChallengeType::cases(), 'value'));
|
||||
$table->string('blueprint_path');
|
||||
$table->enum('faction', array_column(Faction::cases(), 'value'));
|
||||
$table->integer('completion_value');
|
||||
$table->datetime('start_time');
|
||||
$table->datetime('end_time');
|
||||
$table->json('rewards')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('timed_challenges');
|
||||
}
|
||||
};
|
||||
33
dist/database/migrations/2024_12_03_203904_create_player_data_timed_chalenge_table.php
vendored
Normal file
33
dist/database/migrations/2024_12_03_203904_create_player_data_timed_chalenge_table.php
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('player_data_timed_challenge', function (Blueprint $table) {
|
||||
$table->foreignId('timed_challenge_id')->constrained()->cascadeOnDelete()->cascadeOnUpdate();
|
||||
$table->foreignId('player_data_id')->constrained('player_data')->cascadeOnDelete()->cascadeOnUpdate();
|
||||
$table->unsignedInteger('progress')->default(0);
|
||||
$table->boolean('claimed')->default(false);
|
||||
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['timed_challenge_id', 'player_data_id'], 'unique_primary');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('player_data_timed_challenge');
|
||||
}
|
||||
};
|
||||
30
dist/database/migrations/2024_12_19_185927_currency_cap.php
vendored
Normal file
30
dist/database/migrations/2024_12_19_185927_currency_cap.php
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
const USER_MIGRATION_CURRENCY = 10000;
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
\App\Models\User\PlayerData::query()->update([
|
||||
'currency_a' => self::USER_MIGRATION_CURRENCY,
|
||||
'currency_b' => self::USER_MIGRATION_CURRENCY,
|
||||
'currency_c' => self::USER_MIGRATION_CURRENCY,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
};
|
||||
54
dist/database/migrations/2025_08_02_183241_add_child_to_game_files_table.php
vendored
Normal file
54
dist/database/migrations/2025_08_02_183241_add_child_to_game_files_table.php
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
use App\Enums\Launcher\FileAction;
|
||||
use App\Models\GameFile;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
if (Schema::hasIndex('game_files', ['filename', 'hash', 'patchline'])) {
|
||||
Schema::table('game_files', function (Blueprint $table) {
|
||||
$table->dropUnique(['filename', 'hash', 'patchline']);
|
||||
});
|
||||
}
|
||||
|
||||
if (Schema::hasIndex('game_files', ['name'])) {
|
||||
Schema::table('game_files', function (Blueprint $table) {
|
||||
$table->dropUnique(['name']);
|
||||
});
|
||||
}
|
||||
|
||||
Schema::table('game_files', function (Blueprint $table) {
|
||||
$table->foreignId('child_id')->nullable()->after('id')->constrained('game_files')->cascadeOnDelete();
|
||||
$table->unique(['filename', 'hash', 'patchline', 'child_id']);
|
||||
$table->unique(['name', 'child_id']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
// Remove all child records
|
||||
GameFile::whereNotNull('child_id')->each(function ($gameFile) {
|
||||
$gameFile->delete();
|
||||
});
|
||||
|
||||
Schema::table('game_files', function (Blueprint $table) {
|
||||
$table->dropUnique(['filename', 'hash', 'patchline', 'child_id']);
|
||||
$table->dropUnique(['name', 'child_id']);
|
||||
$table->dropForeign('game_files_child_id_foreign');
|
||||
$table->dropColumn('child_id');
|
||||
$table->unique(['filename', 'hash', 'patchline']);
|
||||
$table->unique('name');
|
||||
});
|
||||
}
|
||||
};
|
||||
152
dist/database/seeders/MatchConfigSeeder.php
vendored
152
dist/database/seeders/MatchConfigSeeder.php
vendored
|
|
@ -14,47 +14,54 @@ class MatchConfigSeeder extends Seeder
|
|||
public function run(): void
|
||||
{
|
||||
DB::table('match_configurations')->delete();
|
||||
MatchConfiguration::Create([
|
||||
'name' => 'Matchconfig_Dev - 1v1',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_Demo_HarvestYourExit_1v5.MatchConfig_Demo_HarvestYourExit_1v5',
|
||||
'hunters' => 1,
|
||||
'runners' => 1,
|
||||
'enabled' => false,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
'name' => 'Matchconfig - 1v5',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_Demo_HarvestYourExit_1v5.MatchConfig_Demo_HarvestYourExit_1v5',
|
||||
'enabled' => false,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
'name' => 'Matchconfig - 1v4',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_Demo_2v10_4Needles.MatchConfig_Demo_2v10_4Needles',
|
||||
'enabled' => true,
|
||||
'weight' => 40,
|
||||
'hunters' => 1,
|
||||
'runners' => 4,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
'name' => 'Matchconfig - 1v6',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_Demo_2v8_4Needles.MatchConfig_Demo_2v8_4Needles',
|
||||
'hunters' => 1,
|
||||
'runners' => 6,
|
||||
'enabled' => true,
|
||||
'weight' => 500,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
'name' => 'Halloween Mode - Survival',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_Demo_HarvestYourExit.MatchConfig_Demo_HarvestYourExit',
|
||||
'enabled' => false,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
'name' => 'Curefew 1v5 - Slums',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_SLU_DownTown.MatchConfig_SLU_DownTown',
|
||||
'enabled' => false,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
'name' => 'Harvest Your Exit - 1v5',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_Demo_HarvestYourExit_1v5.MatchConfig_Demo_HarvestYourExit_1v5',
|
||||
'enabled' => false,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
'name' => 'Harvest Your Exit - 1v4',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_Demo_HarvestYourExit_1v5.MatchConfig_Demo_HarvestYourExit_1v5',
|
||||
'enabled' => false,
|
||||
'hunters' => 1,
|
||||
'runners' => 4,
|
||||
'weight' => 10,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
'name' => 'Harvest Your Exit - 1v6',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_Demo_HarvestYourExit_1v5.MatchConfig_Demo_HarvestYourExit_1v5',
|
||||
'enabled' => false,
|
||||
'hunters' => 1,
|
||||
'runners' => 6,
|
||||
'weight' => 10,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
'name' => 'New Arctic Fortress',
|
||||
'name' => 'Frosthold Citadel',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_ARC_Fortress.MatchConfig_ARC_Fortress',
|
||||
'enabled' => true,
|
||||
'weight' => 50,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
'name' => 'Survival 1v5 - All Maps',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_Demo.MatchConfig_Demo',
|
||||
'enabled' => false,
|
||||
'weight' => 50,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
'name' => 'Fire in the Sky - 1v5',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_ARC_BlastFurnace.MatchConfig_ARC_BlastFurnace',
|
||||
'enabled' => true,
|
||||
'enabled' => false,
|
||||
'weight' => 200,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
|
|
@ -100,51 +107,6 @@ public function run(): void
|
|||
'hunters' => 2,
|
||||
'runners' => 10,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
'name' => 'Custom',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_Custom.MatchConfig_Custom',
|
||||
'enabled' => false,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
'name' => 'Custom Match',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_CustomMatch.MatchConfig_CustomMatch',
|
||||
'enabled' => false,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
'name' => 'Survival 2v10 - 4 Needles',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_Demo_2v10_4Needles.MatchConfig_Demo_2v10_4Needles',
|
||||
'enabled' => false,
|
||||
'hunters' => 2,
|
||||
'runners' => 10,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
'name' => 'Survival 2v10 - 5 Needles',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_Demo_2v10_5Needles.MatchConfig_Demo_2v10_5Needles',
|
||||
'enabled' => false,
|
||||
'hunters' => 2,
|
||||
'runners' => 10,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
'name' => 'Survival 2v8 - 4 Needles',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_Demo_2v8_4Needles.MatchConfig_Demo_2v8_4Needles',
|
||||
'enabled' => false,
|
||||
'hunters' => 2,
|
||||
'runners' => 8,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
'name' => 'Survival 2v8 - 5 Needles',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_Demo_2v8_5Needles.MatchConfig_Demo_2v8_5Needles',
|
||||
'enabled' => false,
|
||||
'hunters' => 2,
|
||||
'runners' => 8,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
'name' => 'Harvest Your Exit - 2v10',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_Demo_HarvestYourExit.MatchConfig_Demo_HarvestYourExit',
|
||||
'enabled' => false,
|
||||
'hunters' => 2,
|
||||
'runners' => 10,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
'name' => 'Barren City - 1v5',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_DES_City.MatchConfig_DES_City',
|
||||
|
|
@ -160,7 +122,7 @@ public function run(): void
|
|||
MatchConfiguration::Create([
|
||||
'name' => 'Legions Rest - 1v5',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_DES_Fortress.MatchConfig_DES_Fortress',
|
||||
'enabled' => true,
|
||||
'enabled' => false,
|
||||
'weight' => 100,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
|
|
@ -186,7 +148,7 @@ public function run(): void
|
|||
MatchConfiguration::Create([
|
||||
'name' => 'Dust & Blood - 1v5',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_DES_Mayan.MatchConfig_DES_Mayan',
|
||||
'enabled' => true,
|
||||
'enabled' => false,
|
||||
'weight' => 100,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
|
|
@ -199,7 +161,7 @@ public function run(): void
|
|||
MatchConfiguration::Create([
|
||||
'name' => 'Blowout - 1v5',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_DES_Oilfield.MatchConfig_DES_Oilfield',
|
||||
'enabled' => true,
|
||||
'enabled' => false,
|
||||
'weight' => 100,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
|
|
@ -212,7 +174,7 @@ public function run(): void
|
|||
MatchConfiguration::Create([
|
||||
'name' => 'Forest Citadel - 1v5',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_JUN_Fortress.MatchConfig_JUN_Fortress',
|
||||
'enabled' => true,
|
||||
'enabled' => false,
|
||||
'weight' => 50,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
|
|
@ -222,20 +184,10 @@ public function run(): void
|
|||
'hunters' => 2,
|
||||
'runners' => 10,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
'name' => 'New Maps',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_NewMaps.MatchConfig_NewMaps',
|
||||
'enabled' => false,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
'name' => 'All New Arctic Maps',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_PRM_Special.MatchConfig_PRM_Special',
|
||||
'enabled' => false,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
'name' => 'First Strike - 1v5',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_RUI_All.MatchConfig_RUI_All',
|
||||
'enabled' => true,
|
||||
'enabled' => false,
|
||||
'weight' => 100,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
|
|
@ -246,13 +198,13 @@ public function run(): void
|
|||
'runners' => 10,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
'name' => 'Tombstone - 1v5',
|
||||
'name' => 'Echoes From The Past - 1v5',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_WA_Cemetery.MatchConfig_WA_Cemetery',
|
||||
'enabled' => true,
|
||||
'enabled' => false,
|
||||
'weight' => 140,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
'name' => 'Tombstone - 2v10',
|
||||
'name' => 'Echoes From The Past - 2v10',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_WA_Cemetery_2Hunters.MatchConfig_WA_Cemetery_2Hunters',
|
||||
'enabled' => false,
|
||||
'hunters' => 2,
|
||||
|
|
@ -261,7 +213,7 @@ public function run(): void
|
|||
MatchConfiguration::Create([
|
||||
'name' => 'Salt Creek - 1v5',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_WA_Rivers.MatchConfig_WA_Rivers',
|
||||
'enabled' => true,
|
||||
'enabled' => false,
|
||||
'weight' => 200,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
|
|
@ -271,19 +223,5 @@ public function run(): void
|
|||
'hunters' => 2,
|
||||
'runners' => 10,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
'name' => 'Harvest Your Exit - 1v1 (DEV)',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_Demo_HarvestYourExit_1v5.MatchConfig_Demo_HarvestYourExit_1v5',
|
||||
'hunters' => 1,
|
||||
'runners' => 1,
|
||||
'enabled' => false,
|
||||
]);
|
||||
MatchConfiguration::Create([
|
||||
'name' => 'Harvest Your Exit - 1v6 (EXPERIMENTAL)',
|
||||
'asset_path' => '/Game/Configuration/MatchConfig/MatchConfig_Demo_HarvestYourExit_1v5.MatchConfig_Demo_HarvestYourExit_1v5',
|
||||
'hunters' => 1,
|
||||
'runners' => 6,
|
||||
'enabled' => false,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
3
dist/docker-compose.yml
vendored
3
dist/docker-compose.yml
vendored
|
|
@ -18,7 +18,8 @@ services:
|
|||
XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
|
||||
IGNITION_LOCAL_SITES_PATH: '${PWD}'
|
||||
PHP_IDE_CONFIG: 'serverName=Docker'
|
||||
SUPERVISOR_PHP_COMMAND: "/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan octane:start --server=frankenphp --watch --host=0.0.0.0 --admin-port=2019 --port=80"
|
||||
# Uncomment if you want to enable octane locally
|
||||
#SUPERVISOR_PHP_COMMAND: "/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan octane:start --server=frankenphp --watch --host=0.0.0.0 --admin-port=2019 --port=80"
|
||||
XDG_CONFIG_HOME: /var/www/html/config
|
||||
XDG_DATA_HOME: /var/www/html/data
|
||||
volumes:
|
||||
|
|
|
|||
888
dist/package-lock.json
generated
vendored
888
dist/package-lock.json
generated
vendored
File diff suppressed because it is too large
Load Diff
2
dist/package.json
vendored
2
dist/package.json
vendored
|
|
@ -17,8 +17,6 @@
|
|||
"vite": "^5.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@inertiajs/vue3": "^1.0.14",
|
||||
"@vitejs/plugin-vue": "^5.0.3",
|
||||
"alpinejs": "^3.13.7",
|
||||
"dotenv": "^16.4.2",
|
||||
"jquery": "^3.7.1",
|
||||
|
|
|
|||
BIN
dist/public/img/launcher_img.png
vendored
BIN
dist/public/img/launcher_img.png
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 965 KiB After Width: | Height: | Size: 900 KiB |
BIN
dist/public/img/logos/DG_Rebirth_Logo.png
vendored
BIN
dist/public/img/logos/DG_Rebirth_Logo.png
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 362 KiB After Width: | Height: | Size: 3.3 MiB |
|
|
@ -49,7 +49,7 @@
|
|||
"RequiredChallengesToComplete": [
|
||||
{
|
||||
"ChallengeId": "400AE859-456112F4-EB7516A4-2821AEF3",
|
||||
"ChallengeCompletionValue": 25.0,
|
||||
"ChallengeCompletionValue": 20.0,
|
||||
"ChallengeAsset": {
|
||||
"AssetPathName": "/Game/Challenges/Progression/Challenge_Autocollect_Hunter.Challenge_Autocollect_Hunter",
|
||||
"SubPathString": ""
|
||||
|
|
@ -106,4 +106,4 @@
|
|||
"Version": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
"RequiredChallengesToComplete": [
|
||||
{
|
||||
"ChallengeId": "8DAE5C09-43DA33C2-8E82FC92-B9644702",
|
||||
"ChallengeCompletionValue": 63.0,
|
||||
"ChallengeCompletionValue": 50.0,
|
||||
"ChallengeAsset": {
|
||||
"AssetPathName": "/Game/Challenges/Progression/Challenge_Autocollect_Hunter.Challenge_Autocollect_Hunter",
|
||||
"SubPathString": ""
|
||||
|
|
@ -110,4 +110,4 @@
|
|||
"Version": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
"RequiredChallengesToComplete": [
|
||||
{
|
||||
"ChallengeId": "6DFAA855-48F1C349-CE1E6A9F-29188FCF",
|
||||
"ChallengeCompletionValue": 250.0,
|
||||
"ChallengeCompletionValue": 100.0,
|
||||
"ChallengeAsset": {
|
||||
"AssetPathName": "/Game/Challenges/Progression/Challenge_Autocollect_Hunter.Challenge_Autocollect_Hunter",
|
||||
"SubPathString": ""
|
||||
|
|
@ -106,4 +106,4 @@
|
|||
"Version": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
"RequiredChallengesToComplete": [
|
||||
{
|
||||
"ChallengeId": "590D3041-42028901-1FB868A8-9A43F7CF",
|
||||
"ChallengeCompletionValue": 15.0,
|
||||
"ChallengeCompletionValue": 5.0,
|
||||
"ChallengeAsset": {
|
||||
"AssetPathName": "/Game/Challenges/Progression/Challenge_Hacker_Hunter.Challenge_Hacker_Hunter",
|
||||
"SubPathString": ""
|
||||
|
|
@ -106,4 +106,4 @@
|
|||
"Version": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
"RequiredChallengesToComplete": [
|
||||
{
|
||||
"ChallengeId": "CF29BA96-4B65E429-DD2B559A-4D335CD3",
|
||||
"ChallengeCompletionValue": 38.0,
|
||||
"ChallengeCompletionValue": 15.0,
|
||||
"ChallengeAsset": {
|
||||
"AssetPathName": "/Game/Challenges/Progression/Challenge_Hacker_Hunter.Challenge_Hacker_Hunter",
|
||||
"SubPathString": ""
|
||||
|
|
@ -110,4 +110,4 @@
|
|||
"Version": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
"RequiredChallengesToComplete": [
|
||||
{
|
||||
"ChallengeId": "32749AFC-47E7C872-933FC9AB-8E76AD61",
|
||||
"ChallengeCompletionValue": 150.0,
|
||||
"ChallengeCompletionValue": 30.0,
|
||||
"ChallengeAsset": {
|
||||
"AssetPathName": "/Game/Challenges/Progression/Challenge_Hacker_Hunter.Challenge_Hacker_Hunter",
|
||||
"SubPathString": ""
|
||||
|
|
@ -106,4 +106,4 @@
|
|||
"Version": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
"RequiredChallengesToComplete": [
|
||||
{
|
||||
"ChallengeId": "0EAEAA3C-494F4F47-A35AF885-FDAD8939",
|
||||
"ChallengeCompletionValue": 120.0,
|
||||
"ChallengeCompletionValue": 90.0,
|
||||
"ChallengeAsset": {
|
||||
"AssetPathName": "/Game/Challenges/Progression/Challenge_HackedCratesExplode_Hunter.Challenge_HackedCratesExplode_Hunter",
|
||||
"SubPathString": ""
|
||||
|
|
@ -106,4 +106,4 @@
|
|||
"Version": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
"RequiredChallengesToComplete": [
|
||||
{
|
||||
"ChallengeId": "43AB4B23-4479F000-2C8D798F-583CF6F4",
|
||||
"ChallengeCompletionValue": 300.0,
|
||||
"ChallengeCompletionValue": 120.0,
|
||||
"ChallengeAsset": {
|
||||
"AssetPathName": "/Game/Challenges/Progression/Challenge_HackedCratesExplode_Hunter.Challenge_HackedCratesExplode_Hunter",
|
||||
"SubPathString": ""
|
||||
|
|
@ -110,4 +110,4 @@
|
|||
"Version": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
"RequiredChallengesToComplete": [
|
||||
{
|
||||
"ChallengeId": "0DEBB341-41DD7D71-9EE5C199-707ED8E4",
|
||||
"ChallengeCompletionValue": 1200.0,
|
||||
"ChallengeCompletionValue": 150.0,
|
||||
"ChallengeAsset": {
|
||||
"AssetPathName": "/Game/Challenges/Progression/Challenge_HackedCratesExplode_Hunter.Challenge_HackedCratesExplode_Hunter",
|
||||
"SubPathString": ""
|
||||
|
|
@ -106,4 +106,4 @@
|
|||
"Version": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
"RequiredChallengesToComplete": [
|
||||
{
|
||||
"ChallengeId": "21CBC39E-4B2D8C37-439881A5-879570EC",
|
||||
"ChallengeCompletionValue": 15.0,
|
||||
"ChallengeCompletionValue": 10.0,
|
||||
"ChallengeAsset": {
|
||||
"AssetPathName": "/Game/Challenges/Progression/Challenge_SuddenInsight_Runner.Challenge_SuddenInsight_Runner",
|
||||
"SubPathString": ""
|
||||
|
|
@ -106,4 +106,4 @@
|
|||
"Version": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
"RequiredChallengesToComplete": [
|
||||
{
|
||||
"ChallengeId": "9BB2D0A0-4B6B1683-25E9A080-E84EBD05",
|
||||
"ChallengeCompletionValue": 38.0,
|
||||
"ChallengeCompletionValue": 15.0,
|
||||
"ChallengeAsset": {
|
||||
"AssetPathName": "/Game/Challenges/Progression/Challenge_SuddenInsight_Runner.Challenge_SuddenInsight_Runner",
|
||||
"SubPathString": ""
|
||||
|
|
@ -110,4 +110,4 @@
|
|||
"Version": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
"RequiredChallengesToComplete": [
|
||||
{
|
||||
"ChallengeId": "CF611386-4077974B-00CD37B5-1736426B",
|
||||
"ChallengeCompletionValue": 150.0,
|
||||
"ChallengeCompletionValue": 20.0,
|
||||
"ChallengeAsset": {
|
||||
"AssetPathName": "/Game/Challenges/Progression/Challenge_SuddenInsight_Runner.Challenge_SuddenInsight_Runner",
|
||||
"SubPathString": ""
|
||||
|
|
@ -106,4 +106,4 @@
|
|||
"Version": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
"RequiredChallengesToComplete": [
|
||||
{
|
||||
"ChallengeId": "B4B156CC-47C8D987-B9BDBEB9-10B12C9E",
|
||||
"ChallengeCompletionValue": 60.0,
|
||||
"ChallengeCompletionValue": 50.0,
|
||||
"ChallengeAsset": {
|
||||
"AssetPathName": "/Game/Challenges/Progression/Challenge_AmmoOpportunist_Runner.Challenge_AmmoOpportunist_Runner",
|
||||
"SubPathString": ""
|
||||
|
|
@ -115,4 +115,4 @@
|
|||
"Version": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
"RequiredChallengesToComplete": [
|
||||
{
|
||||
"ChallengeId": "15C92554-4AA67E20-214C8AB0-9F5B33E9",
|
||||
"ChallengeCompletionValue": 150.0,
|
||||
"ChallengeCompletionValue": 75.0,
|
||||
"ChallengeAsset": {
|
||||
"AssetPathName": "/Game/Challenges/Progression/Challenge_AmmoOpportunist_Runner.Challenge_AmmoOpportunist_Runner",
|
||||
"SubPathString": ""
|
||||
|
|
@ -119,4 +119,4 @@
|
|||
"Version": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
"RequiredChallengesToComplete": [
|
||||
{
|
||||
"ChallengeId": "950524C1-44BE794A-ABFFED81-42C119B4",
|
||||
"ChallengeCompletionValue": 600.0,
|
||||
"ChallengeCompletionValue": 100.0,
|
||||
"ChallengeAsset": {
|
||||
"AssetPathName": "/Game/Challenges/Progression/Challenge_AmmoOpportunist_Runner.Challenge_AmmoOpportunist_Runner",
|
||||
"SubPathString": ""
|
||||
|
|
@ -115,4 +115,4 @@
|
|||
"Version": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
"RequiredChallengesToComplete": [
|
||||
{
|
||||
"ChallengeId": "FD314A69-4D049989-202D01BC-36269F44",
|
||||
"ChallengeCompletionValue": 150.0,
|
||||
"ChallengeCompletionValue": 100.0,
|
||||
"ChallengeAsset": {
|
||||
"AssetPathName": "/Game/Challenges/Progression/Challenge_FleetFeet_Runner.Challenge_FleetFeet_Runner",
|
||||
"SubPathString": ""
|
||||
|
|
@ -106,4 +106,4 @@
|
|||
"Version": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
"RequiredChallengesToComplete": [
|
||||
{
|
||||
"ChallengeId": "0A728AD5-4AF5EAB6-CB4356A0-74F01C1B",
|
||||
"ChallengeCompletionValue": 375.0,
|
||||
"ChallengeCompletionValue": 250.0,
|
||||
"ChallengeAsset": {
|
||||
"AssetPathName": "/Game/Challenges/Progression/Challenge_FleetFeet_Runner.Challenge_FleetFeet_Runner",
|
||||
"SubPathString": ""
|
||||
|
|
@ -110,4 +110,4 @@
|
|||
"Version": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
"RequiredChallengesToComplete": [
|
||||
{
|
||||
"ChallengeId": "688EC170-4C4EA4BC-B18181AD-E23E2C3D",
|
||||
"ChallengeCompletionValue": 1500.0,
|
||||
"ChallengeCompletionValue": 500.0,
|
||||
"ChallengeAsset": {
|
||||
"AssetPathName": "/Game/Challenges/Progression/Challenge_FleetFeet_Runner.Challenge_FleetFeet_Runner",
|
||||
"SubPathString": ""
|
||||
|
|
@ -106,4 +106,4 @@
|
|||
"Version": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
"RequiredChallengesToComplete": [
|
||||
{
|
||||
"ChallengeId": "4F99C439-49B5CAC8-7BCEB487-7B7FAB64",
|
||||
"ChallengeCompletionValue": 60.0,
|
||||
"ChallengeCompletionValue": 50.0,
|
||||
"ChallengeAsset": {
|
||||
"AssetPathName": "/Game/Challenges/Progression/Challenge_HeatOfTheMoment_Runner.Challenge_HeatOfTheMoment_Runner",
|
||||
"SubPathString": ""
|
||||
|
|
@ -106,4 +106,4 @@
|
|||
"Version": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
"RequiredChallengesToComplete": [
|
||||
{
|
||||
"ChallengeId": "2ABDC29A-4D174CDC-114AEBAC-B898927E",
|
||||
"ChallengeCompletionValue": 150.0,
|
||||
"ChallengeCompletionValue": 75.0,
|
||||
"ChallengeAsset": {
|
||||
"AssetPathName": "/Game/Challenges/Progression/Challenge_HeatOfTheMoment_Runner.Challenge_HeatOfTheMoment_Runner",
|
||||
"SubPathString": ""
|
||||
|
|
@ -110,4 +110,4 @@
|
|||
"Version": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
"RequiredChallengesToComplete": [
|
||||
{
|
||||
"ChallengeId": "37B650F1-45BF27B3-B670CB9D-84D58111",
|
||||
"ChallengeCompletionValue": 600.0,
|
||||
"ChallengeCompletionValue": 100.0,
|
||||
"ChallengeAsset": {
|
||||
"AssetPathName": "/Game/Challenges/Progression/Challenge_HeatOfTheMoment_Runner.Challenge_HeatOfTheMoment_Runner",
|
||||
"SubPathString": ""
|
||||
|
|
@ -106,4 +106,4 @@
|
|||
"Version": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
"RequiredChallengesToComplete": [
|
||||
{
|
||||
"ChallengeId": "CA2FE47E-45EE792D-FA26FFA3-A30FC0A3",
|
||||
"ChallengeCompletionValue": 60.0,
|
||||
"ChallengeCompletionValue": 30.0,
|
||||
"ChallengeAsset": {
|
||||
"AssetPathName": "/Game/Challenges/Progression/Challenge_HealFaster_Runner.Challenge_HealFaster_Runner",
|
||||
"SubPathString": ""
|
||||
|
|
@ -106,4 +106,4 @@
|
|||
"Version": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
"RequiredChallengesToComplete": [
|
||||
{
|
||||
"ChallengeId": "0E514F8A-467DB3E7-DEBF99AB-AC2313A0",
|
||||
"ChallengeCompletionValue": 150.0,
|
||||
"ChallengeCompletionValue": 60.0,
|
||||
"ChallengeAsset": {
|
||||
"AssetPathName": "/Game/Challenges/Progression/Challenge_HealFaster_Runner.Challenge_HealFaster_Runner",
|
||||
"SubPathString": ""
|
||||
|
|
@ -110,4 +110,4 @@
|
|||
"Version": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
"RequiredChallengesToComplete": [
|
||||
{
|
||||
"ChallengeId": "DE925104-43074D9D-B518B7A9-3A3A2FD9",
|
||||
"ChallengeCompletionValue": 600.0,
|
||||
"ChallengeCompletionValue": 90.0,
|
||||
"ChallengeAsset": {
|
||||
"AssetPathName": "/Game/Challenges/Progression/Challenge_HealFaster_Runner.Challenge_HealFaster_Runner",
|
||||
"SubPathString": ""
|
||||
|
|
@ -106,4 +106,4 @@
|
|||
"Version": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -6,81 +6,95 @@
|
|||
/** @var Patchline $patchline */
|
||||
@endphp
|
||||
|
||||
<x-layouts.admin>
|
||||
<div class="w-full p-2 md:px-16 bg-inherit container mx-auto">
|
||||
<h1 class="text-4xl font-semilight py-10">Deathgarden file manager</h1>
|
||||
|
||||
<form action="{{ url()->current() }}" method="GET">
|
||||
<div class="flex items-center my-4 w-1/2">
|
||||
<div class="flex-auto">
|
||||
<label for="patchlines" class="mr-4 font-medium text-gray-900 dark:text-white">Select a
|
||||
patchline:</label>
|
||||
<x-inputs.dropdown
|
||||
id="patchlines"
|
||||
required
|
||||
name="patchline"
|
||||
:cases="Patchline::cases()"
|
||||
:selected="$patchline"
|
||||
onchange="this.form.submit()" />
|
||||
</div>
|
||||
<div class="flex flex-auto">
|
||||
<label for="additional_files">Show additional mods:</label>
|
||||
<x-inputs.checkbox
|
||||
class="w-6 h-6 ml-4"
|
||||
id="additional_files"
|
||||
name="additional_files"
|
||||
:checked="$showAdditionalFiles"
|
||||
value="1"
|
||||
onchange="this.form.submit()" />
|
||||
</div>
|
||||
<x-layouts.admin>
|
||||
<div class="w-full p-2 md:px-16 bg-inherit container mx-auto">
|
||||
<h1 class="text-4xl font-semilight py-10">Deathgarden file manager</h1>
|
||||
<form action="{{ url()->current() }}" method="GET">
|
||||
<div class="flex items-center my-4 w-1/2">
|
||||
<div class="flex-auto">
|
||||
<label for="patchlines" class="mr-4 font-medium text-gray-900 dark:text-white">
|
||||
Select a patchline:
|
||||
</label>
|
||||
<x-inputs.dropdown
|
||||
id="patchlines"
|
||||
name="patchline"
|
||||
:cases="Patchline::cases()"
|
||||
:selected="$patchline"
|
||||
onchange="this.form.submit()"
|
||||
required />
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="flex flex-auto">
|
||||
<label for="additional_files">
|
||||
Show additional mods:
|
||||
</label>
|
||||
<x-inputs.checkbox
|
||||
class="w-6 h-6 ml-4"
|
||||
id="additional_files"
|
||||
name="additional_files"
|
||||
:checked="$showAdditionalFiles"
|
||||
value="1"
|
||||
onchange="this.form.submit()" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="flex flex-col items-center justify-center">
|
||||
<table>
|
||||
<thead>
|
||||
@if($showAdditionalFiles)
|
||||
<div class="flex flex-col items-center justify-center">
|
||||
<table>
|
||||
<thead>
|
||||
<th class="w-12"></th>
|
||||
@if ($showAdditionalFiles)
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
<th>Filename / Hash</th>
|
||||
@else
|
||||
@else
|
||||
<th>Filename</th>
|
||||
<th>Hash</th>
|
||||
@endif
|
||||
<th class="w-24">Size</th>
|
||||
<th class="w-32">Last update</th>
|
||||
<th>Actions</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($files as $file)
|
||||
<tr @class([ 'text-center' , '!bg-green-600 hover:!bg-green-500'=> $file->action === FileAction::ADD,
|
||||
'!bg-red-600 hover:!bg-red-500' => $file->action === FileAction::DELETE
|
||||
])
|
||||
>
|
||||
@if($showAdditionalFiles)
|
||||
@endif
|
||||
<th class="w-24">Size</th>
|
||||
<th class="w-32">Last update</th>
|
||||
<th class="w-36">Actions</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($files as $file)
|
||||
<tr @class([
|
||||
'text-center',
|
||||
'!bg-green-600 hover:!bg-green-500' => $file->action === FileAction::ADD,
|
||||
'!bg-red-600 hover:!bg-red-500' => $file->action === FileAction::DELETE,
|
||||
])>
|
||||
<td>
|
||||
{{ $file->name }}
|
||||
</td>
|
||||
<td>
|
||||
{{ $file->description }}
|
||||
</td>
|
||||
<td title="{{$file->game_path}}">
|
||||
{{ $file->filename }} <br>
|
||||
{{ $file->hash }}
|
||||
@if ($file->children && $file->children->count() > 0)
|
||||
<button class="expand-row" onclick="toggleRow({{ $file->id }})">
|
||||
<x-icons.plus id="icon-plus-{{ $file->id }}" />
|
||||
<x-icons.minus id="icon-minus-{{ $file->id }}" class="hidden" />
|
||||
</button>
|
||||
@endif
|
||||
</td>
|
||||
@if ($showAdditionalFiles)
|
||||
<td>
|
||||
{{ $file->name }}
|
||||
</td>
|
||||
<td>
|
||||
{{ $file->description }}
|
||||
</td>
|
||||
<td title="{{ $file->game_path }}">
|
||||
{{ $file->filename }} <br>
|
||||
{{ $file->hash }}
|
||||
</td>
|
||||
@else
|
||||
<td title="{{$file->game_path}}">
|
||||
{{ $file->filename }}
|
||||
</td>
|
||||
<td>
|
||||
{{ $file->hash }}
|
||||
</td>
|
||||
<td title="{{ $file->game_path }}">
|
||||
{{ $file->filename }}
|
||||
{{ $file->parent }}
|
||||
</td>
|
||||
<td>
|
||||
{{ $file->hash }}
|
||||
</td>
|
||||
@endif
|
||||
<td>
|
||||
@if($file->fileExists())
|
||||
{{ round($file->getFileSize() / 1000, 1) }} kB
|
||||
@if ($file->fileExists())
|
||||
{{ round($file->getFileSize() / 1000, 1) }} kB
|
||||
@else
|
||||
Error while fetching file
|
||||
N/A
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
|
|
@ -91,9 +105,11 @@ class="w-6 h-6 ml-4"
|
|||
method="POST">
|
||||
@method('PUT')
|
||||
@csrf
|
||||
<button class="">Mark for {{ $file->action->value ? 'delete' : 'add' }}</button>
|
||||
<button class="">Mark for
|
||||
{{ $file->action->value ? 'delete' : 'add' }}</button>
|
||||
</form>
|
||||
<form action="{{ route('file-manager.destroy', ['file_manager' => $file->id]) }}"
|
||||
<form
|
||||
action="{{ route('file-manager.destroy', ['file_manager' => $file->getTopParent()->id]) }}"
|
||||
method="POST">
|
||||
@method('DELETE')
|
||||
@csrf
|
||||
|
|
@ -104,17 +120,58 @@ class="w-6 h-6 ml-4"
|
|||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="mx-auto w-full max-w-screen-2xl mt-8">
|
||||
<form action="{{ route('file-manager.store') }}" method="POST" enctype="multipart/form-data">
|
||||
<input type="hidden" name="patchline" value="{{ request()->input('patchline') ?? '0' }}">
|
||||
<input type="hidden" name="is_additional" value="{{ request()->input('additional_files') ?? '0' }}">
|
||||
@csrf
|
||||
<div id="fileInputsContainer">
|
||||
@if($showAdditionalFiles)
|
||||
@if ($file->children && $file->children->count() > 0)
|
||||
<tr class="expandable-content hidden hover:bg-opacity-60" id="content-{{ $file->id }}">
|
||||
<td></td>
|
||||
<td class="p-0" colspan="{{ $showAdditionalFiles ? '7' : '5' }}">
|
||||
<table class="w-full text-center">
|
||||
<thead>
|
||||
<tr class="pointer-events-none">
|
||||
@if ($showAdditionalFiles)
|
||||
<th class="p-2 border-b-2 border-inherit w-36">File uploaded</th>
|
||||
<th class="p-2 border-b-2 border-inherit">Description</th>
|
||||
@else
|
||||
<th class="p-2 border-b-2 border-inherit w-64">File uploaded</th>
|
||||
@endif
|
||||
<th class="p-2 border-b-2 border-inherit w-72">Hash</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($file->children as $child)
|
||||
<tr @class([
|
||||
'text-center',
|
||||
'!bg-red-600 hover:!bg-red-500' => $child->action === FileAction::ADD,
|
||||
'' => $child->action === FileAction::DELETE,
|
||||
])>
|
||||
<td class="p-2">
|
||||
{{ $child->created_at }}
|
||||
</td>
|
||||
@if ($showAdditionalFiles)
|
||||
<td class="p-2">
|
||||
{{ $child->description }}
|
||||
</td>
|
||||
@endif
|
||||
<td class="p-2">{{ $child->hash }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="mx-auto w-full max-w-screen-2xl mt-8">
|
||||
<form action="{{ route('file-manager.store') }}" method="POST" enctype="multipart/form-data">
|
||||
<input type="hidden" name="patchline" value="{{ request()->input('patchline') ?? '0' }}">
|
||||
<input type="hidden" name="is_additional"
|
||||
value="{{ request()->input('additional_files') ?? '0' }}">
|
||||
@csrf
|
||||
<div id="fileInputsContainer">
|
||||
@if ($showAdditionalFiles)
|
||||
<div class="flex flex-wrap gap-4">
|
||||
<div class="w-2/12 flex items-center mb-2">
|
||||
<x-inputs.text-input name="game_mod_name[]" placeholder="Mod name" />
|
||||
|
|
@ -123,35 +180,33 @@ class="w-6 h-6 ml-4"
|
|||
<x-inputs.text-input name="game_mod_description[]" placeholder="Mod description" />
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
<div class="flex flex-wrap gap-4">
|
||||
<div class="w-6/12 flex items-center mb-2">
|
||||
<x-inputs.text-input name="game_path[]" />
|
||||
</div>
|
||||
<select name="file_action[]"
|
||||
class="w-1/12 rounded-md h-[41.43px] bg-gray-800/75 border border-gray-600 text-white text-sm focus:border-[#6A64F1] focus:shadow-md block px-4 py-2">
|
||||
<option value="1" selected>Add</option>
|
||||
<option value="0">Delete</option>
|
||||
</select>
|
||||
<div class="flex items-center mb-2">
|
||||
<x-inputs.file-input name="files[]" />
|
||||
</div>
|
||||
@endif
|
||||
<div class="flex flex-wrap gap-4">
|
||||
<div class="w-6/12 flex items-center mb-2">
|
||||
<x-inputs.text-input name="game_path[]" />
|
||||
</div>
|
||||
<select name="file_action[]"
|
||||
class="w-1/12 rounded-md h-[41.43px] bg-gray-800/75 border border-gray-600 text-white text-sm focus:border-[#6A64F1] focus:shadow-md block px-4 py-2">
|
||||
<option value="1" selected>Add</option>
|
||||
<option value="0">Delete</option>
|
||||
</select>
|
||||
<div class="flex items-center mb-2">
|
||||
<x-inputs.file-input name="files[]" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end mt-4">
|
||||
@if (!$showAdditionalFiles)
|
||||
<div class="flex justify-end mt-4">
|
||||
@if (!$showAdditionalFiles)
|
||||
<div class="w-auto mx-2">
|
||||
<x-inputs.button type="button" id="addFileInput">
|
||||
Add More Files
|
||||
</x-inputs.button>
|
||||
</div>
|
||||
@endif
|
||||
<div class="w-auto mx-2">
|
||||
<x-inputs.button>
|
||||
Submit
|
||||
</x-inputs.button>
|
||||
</div>
|
||||
@endif
|
||||
<div class="w-auto mx-2">
|
||||
<x-inputs.button>
|
||||
Submit
|
||||
</x-inputs.button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
|
@ -159,19 +214,34 @@ class="w-1/12 rounded-md h-[41.43px] bg-gray-800/75 border border-gray-600 text-
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function addFileInputEventListener(fileInput) {
|
||||
fileInput.addEventListener('change', function(event) {
|
||||
let selectedFile = event.target.files[0];
|
||||
let textInput = event.target.closest('.flex-wrap').querySelector('input[name="game_path[]"]');
|
||||
if (textInput) {
|
||||
if (selectedFile) {
|
||||
var fileName = selectedFile.name;
|
||||
fileName = examineFilePaths(fileName);
|
||||
textInput.value = fileName;
|
||||
} else {
|
||||
textInput.value = '';
|
||||
}
|
||||
<script>
|
||||
function toggleRow(id) {
|
||||
const content = document.getElementById('content-' + id);
|
||||
const iconPlus = document.getElementById('icon-plus-' + id);
|
||||
const iconMinus = document.getElementById('icon-minus-' + id);
|
||||
|
||||
if (content.classList.contains('hidden')) {
|
||||
content.classList.remove('hidden');
|
||||
iconMinus.classList.remove('hidden');
|
||||
iconPlus.classList.add('hidden');
|
||||
} else {
|
||||
content.classList.add('hidden');
|
||||
iconMinus.classList.add('hidden');
|
||||
iconPlus.classList.remove('hidden');
|
||||
}
|
||||
}
|
||||
|
||||
function addFileInputEventListener(fileInput) {
|
||||
fileInput.addEventListener('change', function(event) {
|
||||
let selectedFile = event.target.files[0];
|
||||
let textInput = event.target.closest('.flex-wrap').querySelector('input[name="game_path[]"]');
|
||||
if (textInput) {
|
||||
if (selectedFile) {
|
||||
var fileName = selectedFile.name;
|
||||
fileName = examineFilePaths(fileName);
|
||||
textInput.value = fileName;
|
||||
} else {
|
||||
textInput.value = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -197,7 +267,7 @@ function examineFilePaths(fileName) {
|
|||
}
|
||||
}
|
||||
|
||||
@if(!$showAdditionalFiles)
|
||||
@if (!$showAdditionalFiles)
|
||||
document.getElementById('addFileInput').addEventListener('click', function() {
|
||||
let container = document.getElementById('fileInputsContainer');
|
||||
let newInput = document.createElement('div');
|
||||
|
|
@ -219,11 +289,13 @@ function examineFilePaths(fileName) {
|
|||
// Add event listener to file input of the newly created input group
|
||||
var fileInput = newInput.querySelector('input[name="files[]"]');
|
||||
addFileInputEventListener(fileInput);
|
||||
});
|
||||
@endif
|
||||
|
||||
// Add event listener to file input of the initial input group
|
||||
var initialFileInput = document.querySelector('input[name="files[]"]');
|
||||
addFileInputEventListener(initialFileInput);
|
||||
</script>
|
||||
</x-layouts.admin>
|
||||
window.scrollTo(0, document.body.scrollHeight);
|
||||
});
|
||||
@endif
|
||||
|
||||
// Add event listener to file input of the initial input group
|
||||
var initialFileInput = document.querySelector('input[name="files[]"]');
|
||||
addFileInputEventListener(initialFileInput);
|
||||
</script>
|
||||
</x-layouts.admin>
|
||||
|
|
|
|||
|
|
@ -3,14 +3,15 @@
|
|||
|
||||
$experienceMultipliers = \App\Models\Admin\ExperienceMultipliers::get();
|
||||
$currencyMultipliers = \App\Models\Admin\CurrencyMultipliers::get();
|
||||
$matchmakingSettings = \App\Models\Admin\MatchmakingSettings::get();
|
||||
@endphp
|
||||
|
||||
<x-layouts.admin>
|
||||
<div class="container mx-auto border bg-slate-800 border-slate-500 rounded-xl p-4 my-6">
|
||||
<div class="flex flex-col gap-4 px-4 lg:[&>form>div]:px-52 [&>form>div]:flex [&>form>div]:justify-between [&>form>div]:items-center [&>form_label]:text-xl">
|
||||
<form action="{{ route('match-configuration.save.experience') }}" method="post">
|
||||
<form action="{{ route('match-configuration.save.experience') }}" method="post" class="[&>div]:m-2">
|
||||
@csrf
|
||||
<span class="headline">
|
||||
<span class="headline mb-2">
|
||||
Experience Multipliers
|
||||
</span>
|
||||
|
||||
|
|
@ -139,7 +140,7 @@
|
|||
Save
|
||||
</x-inputs.button>
|
||||
</form>
|
||||
<form action="{{ route('match-configuration.save.currency') }}" method="post" class="mt-8">
|
||||
<form action="{{ route('match-configuration.save.currency') }}" method="post" class="mt-8 [&>div]:m-2">
|
||||
@csrf
|
||||
<span class="headline">
|
||||
Currency Multipliers
|
||||
|
|
@ -190,6 +191,29 @@
|
|||
Save
|
||||
</x-inputs.button>
|
||||
</form>
|
||||
<form action="{{ route('match-configuration.save.matchmaking') }}" method="post" class="mt-8 [&>div]:m-2">
|
||||
@csrf
|
||||
<span class="headline mb-2">
|
||||
Matchmaking Settings
|
||||
</span>
|
||||
|
||||
<div>
|
||||
<label for="matchmakingWaitingTime">
|
||||
1v4 and 1v5 matchmaking wait duration
|
||||
</label>
|
||||
|
||||
<x-inputs.number
|
||||
id="matchmakingWaitingTime"
|
||||
name="matchmakingWaitingTime"
|
||||
value="{{ $matchmakingSettings->matchWaitingTime }}"
|
||||
step="1"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<x-inputs.button class="save mt-2">
|
||||
Save
|
||||
</x-inputs.button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</x-layouts.admin>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user