diff --git a/web/app/Helpers/AssetHelper.php b/web/app/Helpers/AssetHelper.php index 559fabd..d3afcc0 100644 --- a/web/app/Helpers/AssetHelper.php +++ b/web/app/Helpers/AssetHelper.php @@ -41,6 +41,19 @@ class AssetHelper if(!$marketplaceResult->ok() || !$assetResult->ok()) return false; + $assetTypeId = $marketplaceResult['AssetTypeId']; + if( + $assetTypeId == 41 || // Hair Accessory + $assetTypeId == 42 || // Face Accessory + $assetTypeId == 43 || // Neck Accessory + $assetTypeId == 44 || // Shoulder Accessory + $assetTypeId == 45 || // Front Accessory + $assetTypeId == 46 || // Back Accessory + $assetTypeId == 47 // Waist Accessory + ) { + $assetTypeId = 8; + } + $assetContent = Http::get($assetResult['locations'][0]['location']); $hash = CdnHelper::SaveContent($assetContent->body(), $assetContent->header('Content-Type')); $asset = Asset::create([ @@ -50,7 +63,7 @@ class AssetHelper 'approved' => true, 'priceInTokens' => $marketplaceResult['PriceInRobux'] ?: 0, 'onSale' => $marketplaceResult['IsForSale'], - 'assetTypeId' => $marketplaceResult['AssetTypeId'], + 'assetTypeId' => $assetTypeId, 'assetVersionId' => 0 ]); $assetVersion = AssetVersion::create([ @@ -82,6 +95,19 @@ class AssetHelper if(!$marketplaceResult->ok()) return false; + $assetTypeId = $marketplaceResult['AssetTypeId']; + if( + $assetTypeId == 41 || // Hair Accessory + $assetTypeId == 42 || // Face Accessory + $assetTypeId == 43 || // Neck Accessory + $assetTypeId == 44 || // Shoulder Accessory + $assetTypeId == 45 || // Front Accessory + $assetTypeId == 46 || // Back Accessory + $assetTypeId == 47 // Waist Accessory + ) { + $assetTypeId = 8; + } + $hash = CdnHelper::SaveContentB64($b64Content, 'application/octet-stream'); $asset = Asset::create([ 'creatorId' => ($uploadToHolder ? 1 : Auth::user()->id), @@ -90,7 +116,7 @@ class AssetHelper 'approved' => true, 'priceInTokens' => $marketplaceResult['PriceInRobux'] ?: 0, 'onSale' => $marketplaceResult['IsForSale'], - 'assetTypeId' => $marketplaceResult['AssetTypeId'], + 'assetTypeId' => $assetTypeId, 'assetVersionId' => 0 ]); $assetVersion = AssetVersion::create([ diff --git a/web/app/Helpers/BrickColorHelper.php b/web/app/Helpers/BrickColorHelper.php new file mode 100644 index 0000000..11b1071 --- /dev/null +++ b/web/app/Helpers/BrickColorHelper.php @@ -0,0 +1,851 @@ + [ + 'Color' => [242, 243, 243], + 'Name' => 'White' + ], + 2 => [ + 'Color' => [161, 165, 162], + 'Name' => 'Grey' + ], + 3 => [ + 'Color' => [249, 233, 153], + 'Name' => 'Light yellow' + ], + 5 => [ + 'Color' => [215, 197, 154], + 'Name' => 'Brick yellow' + ], + 6 => [ + 'Color' => [194, 218, 184], + 'Name' => 'Light green (Mint)' + ], + 9 => [ + 'Color' => [232, 186, 200], + 'Name' => 'Light reddish violet' + ], + 11 => [ + 'Color' => [0x80, 0xbb, 0xdb], + 'Name' => 'Pastel Blue' + ], + 12 => [ + 'Color' => [203, 132, 66], + 'Name' => 'Light orange brown' + ], + 18 => [ + 'Color' => [204, 142, 105], + 'Name' => 'Nougat' + ], + 21 => [ + 'Color' => [196, 40, 28], + 'Name' => 'Bright red' + ], + 22 => [ + 'Color' => [196, 112, 160], + 'Name' => 'Med. reddish violet' + ], + 23 => [ + 'Color' => [13, 105, 172], + 'Name' => 'Bright blue' + ], + 24 => [ + 'Color' => [245, 205, 48], + 'Name' => 'Bright yellow' + ], + 25 => [ + 'Color' => [98, 71, 50], + 'Name' => 'Earth orange' + ], + 26 => [ + 'Color' => [27, 42, 53], + 'Name' => 'Black' + ], + 27 => [ + 'Color' => [109, 110, 108], + 'Name' => 'Dark grey' + ], + 28 => [ + 'Color' => [40, 127, 71], + 'Name' => 'Dark green' + ], + 29 => [ + 'Color' => [161, 196, 140], + 'Name' => 'Medium green' + ], + 36 => [ + 'Color' => [243, 207, 155], + 'Name' => 'Lig. Yellowich orange' + ], + 37 => [ + 'Color' => [75, 151, 75], + 'Name' => 'Bright green' + ], + 38 => [ + 'Color' => [160, 95, 53], + 'Name' => 'Dark orange' + ], + 39 => [ + 'Color' => [193, 202, 222], + 'Name' => 'Light bluish violet' + ], + 40 => [ + 'Color' => [236, 236, 236], + 'Name' => 'Transparent' + ], + 41 => [ + 'Color' => [205, 84, 75], + 'Name' => 'Tr. Red' + ], + 42 => [ + 'Color' => [193, 223, 240], + 'Name' => 'Tr. Lg blue' + ], + 43 => [ + 'Color' => [123, 182, 232], + 'Name' => 'Tr. Blue' + ], + 44 => [ + 'Color' => [247, 241, 141], + 'Name' => 'Tr. Yellow' + ], + 45 => [ + 'Color' => [180, 210, 228], + 'Name' => 'Light blue' + ], + 47 => [ + 'Color' => [217, 133, 108], + 'Name' => 'Tr. Flu. Reddish orange' + ], + 48 => [ + 'Color' => [132, 182, 141], + 'Name' => 'Tr. Green' + ], + 49 => [ + 'Color' => [248, 241, 132], + 'Name' => 'Tr. Flu. Green' + ], + 50 => [ + 'Color' => [236, 232, 222], + 'Name' => 'Phosph. White' + ], + 100 => [ + 'Color' => [238, 196, 182], + 'Name' => 'Light red' + ], + 101 => [ + 'Color' => [218, 134, 122], + 'Name' => 'Medium red' + ], + 102 => [ + 'Color' => [110, 153, 202], + 'Name' => 'Medium blue' + ], + 103 => [ + 'Color' => [199, 193, 183], + 'Name' => 'Light grey' + ], + 104 => [ + 'Color' => [107, 50, 124], + 'Name' => 'Bright violet' + ], + 105 => [ + 'Color' => [226, 155, 64], + 'Name' => 'Br. yellowish orange' + ], + 106 => [ + 'Color' => [218, 133, 65], + 'Name' => 'Bright orange' + ], + 107 => [ + 'Color' => [0, 143, 156], + 'Name' => 'Bright bluish green' + ], + 108 => [ + 'Color' => [104, 92, 67], + 'Name' => 'Earth yellow' + ], + 110 => [ + 'Color' => [67, 84, 147], + 'Name' => 'Bright bluish violet' + ], + 111 => [ + 'Color' => [191, 183, 177], + 'Name' => 'Tr. Brown' + ], + 112 => [ + 'Color' => [104, 116, 172], + 'Name' => 'Medium bluish violet' + ], + 113 => [ + 'Color' => [228, 173, 200], + 'Name' => 'Tr. Medi. reddish violet' + ], + 115 => [ + 'Color' => [199, 210, 60], + 'Name' => 'Med. yellowish green' + ], + 116 => [ + 'Color' => [85, 165, 175], + 'Name' => 'Med. bluish green' + ], + 118 => [ + 'Color' => [183, 215, 213], + 'Name' => 'Light bluish green' + ], + 119 => [ + 'Color' => [164, 189, 71], + 'Name' => 'Br. yellowish green' + ], + 120 => [ + 'Color' => [217, 228, 167], + 'Name' => 'Lig. yellowish green' + ], + 121 => [ + 'Color' => [231, 172, 88], + 'Name' => 'Med. yellowish orange' + ], + 123 => [ + 'Color' => [211, 111, 76], + 'Name' => 'Br. reddish orange' + ], + 124 => [ + 'Color' => [146, 57, 120], + 'Name' => 'Bright reddish violet' + ], + 125 => [ + 'Color' => [234, 184, 146], + 'Name' => 'Light orange' + ], + 126 => [ + 'Color' => [165, 165, 203], + 'Name' => 'Tr. Bright bluish violet' + ], + 127 => [ + 'Color' => [220, 188, 129], + 'Name' => 'Gold' + ], + 128 => [ + 'Color' => [174, 122, 89], + 'Name' => 'Dark nougat' + ], + 131 => [ + 'Color' => [156, 163, 168], + 'Name' => 'Silver' + ], + 133 => [ + 'Color' => [213, 115, 61], + 'Name' => 'Neon orange' + ], + 134 => [ + 'Color' => [216, 221, 86], + 'Name' => 'Neon green' + ], + 135 => [ + 'Color' => [116, 134, 157], + 'Name' => 'Sand blue' + ], + 136 => [ + 'Color' => [135, 124, 144], + 'Name' => 'Sand violet' + ], + 137 => [ + 'Color' => [224, 152, 100], + 'Name' => 'Medium orange' + ], + 138 => [ + 'Color' => [149, 138, 115], + 'Name' => 'Sand yellow' + ], + 140 => [ + 'Color' => [32, 58, 86], + 'Name' => 'Earth blue' + ], + 141 => [ + 'Color' => [39, 70, 45], + 'Name' => 'Earth green' + ], + 143 => [ + 'Color' => [207, 226, 247], + 'Name' => 'Tr. Flu. Blue' + ], + 145 => [ + 'Color' => [121, 136, 161], + 'Name' => 'Sand blue metallic' + ], + 146 => [ + 'Color' => [149, 142, 163], + 'Name' => 'Sand violet metallic' + ], + 147 => [ + 'Color' => [147, 135, 103], + 'Name' => 'Sand yellow metallic' + ], + 148 => [ + 'Color' => [87, 88, 87], + 'Name' => 'Dark grey metallic' + ], + 149 => [ + 'Color' => [22, 29, 50], + 'Name' => 'Black metallic' + ], + 150 => [ + 'Color' => [171, 173, 172], + 'Name' => 'Light grey metallic' + ], + 151 => [ + 'Color' => [120, 144, 130], + 'Name' => 'Sand green' + ], + 153 => [ + 'Color' => [149, 121, 119], + 'Name' => 'Sand red' + ], + 154 => [ + 'Color' => [123, 46, 47], + 'Name' => 'Dark red' + ], + 157 => [ + 'Color' => [255, 246, 123], + 'Name' => 'Tr. Flu. Yellow' + ], + 158 => [ + 'Color' => [225, 164, 194], + 'Name' => 'Tr. Flu. Red' + ], + 168 => [ + 'Color' => [117, 108, 98], + 'Name' => 'Gun metallic' + ], + 176 => [ + 'Color' => [151, 105, 91], + 'Name' => 'Red flip/flop' + ], + 178 => [ + 'Color' => [180, 132, 85], + 'Name' => 'Yellow flip/flop' + ], + 179 => [ + 'Color' => [137, 135, 136], + 'Name' => 'Silver flip/flop' + ], + 180 => [ + 'Color' => [215, 169, 75], + 'Name' => 'Curry' + ], + 190 => [ + 'Color' => [249, 214, 46], + 'Name' => 'Fire Yellow' + ], + 191 => [ + 'Color' => [232, 171, 45], + 'Name' => 'Flame yellowish orange' + ], + 192 => [ + 'Color' => [105, 64, 40], + 'Name' => 'Reddish brown' + ], + 193 => [ + 'Color' => [207, 96, 36], + 'Name' => 'Flame reddish orange' + ], + 194 => [ + 'Color' => [163, 162, 165], + 'Name' => 'Medium stone grey' + ], + 195 => [ + 'Color' => [70, 103, 164], + 'Name' => 'Royal blue' + ], + 196 => [ + 'Color' => [35, 71, 139], + 'Name' => 'Dark Royal blue' + ], + 198 => [ + 'Color' => [142, 66, 133], + 'Name' => 'Bright reddish lilac' + ], + 199 => [ + 'Color' => [99, 95, 98], + 'Name' => 'Dark stone grey' + ], + 200 => [ + 'Color' => [130, 138, 93], + 'Name' => 'Lemon metalic' + ], + 208 => [ + 'Color' => [229, 228, 223], + 'Name' => 'Light stone grey' + ], + 209 => [ + 'Color' => [176, 142, 68], + 'Name' => 'Dark Curry' + ], + 210 => [ + 'Color' => [112, 149, 120], + 'Name' => 'Faded green' + ], + 211 => [ + 'Color' => [121, 181, 181], + 'Name' => 'Turquoise' + ], + 212 => [ + 'Color' => [159, 195, 233], + 'Name' => 'Light Royal blue' + ], + 213 => [ + 'Color' => [108, 129, 183], + 'Name' => 'Medium Royal blue' + ], + 216 => [ + 'Color' => [143, 76, 42], + 'Name' => 'Rust' + ], + 217 => [ + 'Color' => [124, 92, 70], + 'Name' => 'Brown' + ], + 218 => [ + 'Color' => [150, 112, 159], + 'Name' => 'Reddish lilac' + ], + 219 => [ + 'Color' => [107, 98, 155], + 'Name' => 'Lilac' + ], + 220 => [ + 'Color' => [167, 169, 206], + 'Name' => 'Light lilac' + ], + 221 => [ + 'Color' => [205, 98, 152], + 'Name' => 'Bright purple' + ], + 222 => [ + 'Color' => [228, 173, 200], + 'Name' => 'Light purple' + ], + 223 => [ + 'Color' => [220, 144, 149], + 'Name' => 'Light pink' + ], + 224 => [ + 'Color' => [240, 213, 160], + 'Name' => 'Light brick yellow' + ], + 225 => [ + 'Color' => [235, 184, 127], + 'Name' => 'Warm yellowish orange' + ], + 226 => [ + 'Color' => [253, 234, 141], + 'Name' => 'Cool yellow' + ], + 232 => [ + 'Color' => [125, 187, 221], + 'Name' => 'Dove blue' + ], + 268 => [ + 'Color' => [52, 43, 117], + 'Name' => 'Medium lilac' + ], + 301 => [ + 'Color' => [80, 109, 84], + 'Name' => 'Slime green' + ], + 302 => [ + 'Color' => [91, 93, 105], + 'Name' => 'Smoky grey' + ], + 303 => [ + 'Color' => [0, 16, 176], + 'Name' => 'Dark blue' + ], + 304 => [ + 'Color' => [44, 101, 29], + 'Name' => 'Parsley green' + ], + 305 => [ + 'Color' => [82, 124, 174], + 'Name' => 'Steel blue' + ], + 306 => [ + 'Color' => [51, 88, 130], + 'Name' => 'Storm blue' + ], + 307 => [ + 'Color' => [16, 42, 220], + 'Name' => 'Lapis' + ], + 308 => [ + 'Color' => [61, 21, 133], + 'Name' => 'Dark indigo' + ], + 309 => [ + 'Color' => [52, 142, 64], + 'Name' => 'Sea green' + ], + 310 => [ + 'Color' => [91, 154, 76], + 'Name' => 'Shamrock' + ], + 311 => [ + 'Color' => [159, 161, 172], + 'Name' => 'Fossil' + ], + 312 => [ + 'Color' => [89, 34, 89], + 'Name' => 'Mulberry' + ], + 313 => [ + 'Color' => [31, 128, 29], + 'Name' => 'Forest green' + ], + 314 => [ + 'Color' => [159, 173, 192], + 'Name' => 'Cadet blue' + ], + 315 => [ + 'Color' => [9, 137, 207], + 'Name' => 'Electric blue' + ], + 316 => [ + 'Color' => [123, 0, 123], + 'Name' => 'Eggplant' + ], + 317 => [ + 'Color' => [124, 156, 107], + 'Name' => 'Moss' + ], + 318 => [ + 'Color' => [138, 171, 133], + 'Name' => 'Artichoke' + ], + 319 => [ + 'Color' => [185, 196, 177], + 'Name' => 'Sage green' + ], + 320 => [ + 'Color' => [202, 203, 209], + 'Name' => 'Ghost grey' + ], + 321 => [ + 'Color' => [167, 94, 155], + 'Name' => 'Lilac' + ], + 322 => [ + 'Color' => [123, 47, 123], + 'Name' => 'Plum' + ], + 323 => [ + 'Color' => [148, 190, 129], + 'Name' => 'Olivine' + ], + 324 => [ + 'Color' => [168, 189, 153], + 'Name' => 'Laurel green' + ], + 325 => [ + 'Color' => [223, 223, 222], + 'Name' => 'Quill grey' + ], + 327 => [ + 'Color' => [151, 0, 0], + 'Name' => 'Crimson' + ], + 328 => [ + 'Color' => [177, 229, 166], + 'Name' => 'Mint' + ], + 329 => [ + 'Color' => [152, 194, 219], + 'Name' => 'Baby blue' + ], + 330 => [ + 'Color' => [255, 152, 220], + 'Name' => 'Carnation pink' + ], + 331 => [ + 'Color' => [255, 89, 89], + 'Name' => 'Persimmon' + ], + 332 => [ + 'Color' => [117, 0, 0], + 'Name' => 'Maroon' + ], + 333 => [ + 'Color' => [239, 184, 56], + 'Name' => 'Gold' + ], + 334 => [ + 'Color' => [248, 217, 109], + 'Name' => 'Daisy orange' + ], + 335 => [ + 'Color' => [231, 231, 236], + 'Name' => 'Pearl' + ], + 336 => [ + 'Color' => [199, 212, 228], + 'Name' => 'Fog' + ], + 337 => [ + 'Color' => [255, 148, 148], + 'Name' => 'Salmon' + ], + 338 => [ + 'Color' => [190, 104, 98], + 'Name' => 'Terra Cotta' + ], + 339 => [ + 'Color' => [86, 36, 36], + 'Name' => 'Cocoa' + ], + 340 => [ + 'Color' => [241, 231, 199], + 'Name' => 'Wheat' + ], + 341 => [ + 'Color' => [254, 243, 187], + 'Name' => 'Buttermilk' + ], + 342 => [ + 'Color' => [224, 178, 208], + 'Name' => 'Mauve' + ], + 343 => [ + 'Color' => [212, 144, 189], + 'Name' => 'Sunrise' + ], + 344 => [ + 'Color' => [150, 85, 85], + 'Name' => 'Tawny' + ], + 345 => [ + 'Color' => [143, 76, 42], + 'Name' => 'Rust' + ], + 346 => [ + 'Color' => [211, 190, 150], + 'Name' => 'Cashmere' + ], + 347 => [ + 'Color' => [226, 220, 188], + 'Name' => 'Khaki' + ], + 348 => [ + 'Color' => [237, 234, 234], + 'Name' => 'Lily white' + ], + 349 => [ + 'Color' => [233, 218, 218], + 'Name' => 'Seashell' + ], + 350 => [ + 'Color' => [136, 62, 62], + 'Name' => 'Burgundy' + ], + 351 => [ + 'Color' => [188, 155, 93], + 'Name' => 'Cork' + ], + 352 => [ + 'Color' => [199, 172, 120], + 'Name' => 'Burlap' + ], + 353 => [ + 'Color' => [202, 191, 163], + 'Name' => 'Beige' + ], + 354 => [ + 'Color' => [187, 179, 178], + 'Name' => 'Oyster' + ], + 355 => [ + 'Color' => [108, 88, 75], + 'Name' => 'Pine Cone' + ], + 356 => [ + 'Color' => [160, 132, 79], + 'Name' => 'Fawn brown' + ], + 357 => [ + 'Color' => [149, 137, 136], + 'Name' => 'Hurricane grey' + ], + 358 => [ + 'Color' => [171, 168, 158], + 'Name' => 'Cloudy grey' + ], + 359 => [ + 'Color' => [175, 148, 131], + 'Name' => 'Linen' + ], + 360 => [ + 'Color' => [150, 103, 102], + 'Name' => 'Copper' + ], + 361 => [ + 'Color' => [86, 66, 54], + 'Name' => 'Dirt brown' + ], + 362 => [ + 'Color' => [126, 104, 63], + 'Name' => 'Bronze' + ], + 363 => [ + 'Color' => [105, 102, 92], + 'Name' => 'Flint' + ], + 364 => [ + 'Color' => [90, 76, 66], + 'Name' => 'Dark taupe' + ], + 365 => [ + 'Color' => [106, 57, 9], + 'Name' => 'Burnt Sienna' + ], + 1001 => [ + 'Color' => [248, 248, 248], + 'Name' => 'Institutional white' + ], + 1002 => [ + 'Color' => [205, 205, 205], + 'Name' => 'Mid gray' + ], + 1003 => [ + 'Color' => [17, 17, 17], + 'Name' => 'Really black' + ], + 1004 => [ + 'Color' => [255, 0, 0], + 'Name' => 'Really red' + ], + 1005 => [ + 'Color' => [255, 175, 0], + 'Name' => 'Deep orange' + ], + 1006 => [ + 'Color' => [180, 128, 255], + 'Name' => 'Alder' + ], + 1007 => [ + 'Color' => [163, 75, 75], + 'Name' => 'Dusty Rose' + ], + 1008 => [ + 'Color' => [193, 190, 66], + 'Name' => 'Olive' + ], + 1009 => [ + 'Color' => [255, 255, 0], + 'Name' => 'New Yeller' + ], + 1010 => [ + 'Color' => [0, 0, 255], + 'Name' => 'Really blue' + ], + 1011 => [ + 'Color' => [0, 32, 96], + 'Name' => 'Navy blue' + ], + 1012 => [ + 'Color' => [33, 84, 185], + 'Name' => 'Deep blue' + ], + 1013 => [ + 'Color' => [4, 175, 236], + 'Name' => 'Cyan' + ], + 1014 => [ + 'Color' => [170, 85, 0], + 'Name' => 'CGA brown' + ], + 1015 => [ + 'Color' => [170, 0, 170], + 'Name' => 'Magenta' + ], + 1016 => [ + 'Color' => [255, 102, 204], + 'Name' => 'Pink' + ], + 1017 => [ + 'Color' => [255, 175, 0], + 'Name' => 'Deep orange' + ], + 1018 => [ + 'Color' => [18, 238, 212], + 'Name' => 'Teal' + ], + 1019 => [ + 'Color' => [0, 255, 255], + 'Name' => 'Toothpaste' + ], + 1020 => [ + 'Color' => [0, 255, 0], + 'Name' => 'Lime green' + ], + 1021 => [ + 'Color' => [58, 125, 21], + 'Name' => 'Camo' + ], + 1022 => [ + 'Color' => [127, 142, 100], + 'Name' => 'Grime' + ], + 1023 => [ + 'Color' => [140, 91, 159], + 'Name' => 'Lavender' + ], + 1024 => [ + 'Color' => [175, 221, 255], + 'Name' => 'Pastel light blue' + ], + 1025 => [ + 'Color' => [255, 201, 201], + 'Name' => 'Pastel orange' + ], + 1026 => [ + 'Color' => [177, 167, 255], + 'Name' => 'Pastel violet' + ], + 1027 => [ + 'Color' => [159, 243, 233], + 'Name' => 'Pastel blue-green' + ], + 1028 => [ + 'Color' => [204, 255, 204], + 'Name' => 'Pastel green' + ], + 1029 => [ + 'Color' => [255, 255, 204], + 'Name' => 'Pastel yellow' + ], + 1030 => [ + 'Color' => [255, 204, 153], + 'Name' => 'Pastel brown' + ], + 1031 => [ + 'Color' => [98, 37, 209], + 'Name' => 'Royal purple' + ], + 1032 => [ + 'Color' => [255, 0, 191], + 'Name' => 'Hot pink' + ] + ]; + + public static function IsValidColor($colorId) + { + return array_key_exists($colorId, self::$brickColors); + } +} diff --git a/web/app/Helpers/CdnHelper.php b/web/app/Helpers/CdnHelper.php index a5fb6c1..fa9a22e 100644 --- a/web/app/Helpers/CdnHelper.php +++ b/web/app/Helpers/CdnHelper.php @@ -44,6 +44,21 @@ class CdnHelper return $hash; } + public static function Delete($hash) + { + $disk = self::GetDisk(); + + $cdnHash = CdnHash::where('hash', $hash); + if($disk->exists($hash) && $cdnHash->exists()) { + $cdnHash->delete(); + $disk->delete($hash); + + return true; + } + + return false; + } + public static function SaveContentB64($contentB64, $mime) { return self::SaveContent(base64_decode($contentB64), $mime); diff --git a/web/app/Helpers/GridHelper.php b/web/app/Helpers/GridHelper.php index 5b15978..808311f 100644 --- a/web/app/Helpers/GridHelper.php +++ b/web/app/Helpers/GridHelper.php @@ -123,7 +123,7 @@ class GridHelper public static function getDefaultThumbnail($fileName) { - $disk = $self::getThumbDisk(); + $disk = self::getThumbDisk(); if(!$disk->exists($fileName)) throw new Exception('Unable to locate template file.'); @@ -133,7 +133,26 @@ class GridHelper public static function getUnknownThumbnail() { - return $self::getDefaultThumbnail('UnknownThumbnail.png'); + return self::getDefaultThumbnail('UnknownThumbnail.png'); + } + + private static function getGameDisk() + { + return Storage::build([ + 'driver' => 'local', + 'root' => storage_path('app/grid/game'), + ]); + } + + public static function getBodyColorsXML() + { + $disk = self::getGameDisk(); + $fileName = 'BodyColors.xml'; + + if(!$disk->exists($fileName)) + throw new Exception('Unable to locate template file.'); + + return $disk->get($fileName); } public static function getArbiter($name) diff --git a/web/app/Http/Controllers/Api/AvatarController.php b/web/app/Http/Controllers/Api/AvatarController.php new file mode 100644 index 0000000..5d7a8e7 --- /dev/null +++ b/web/app/Http/Controllers/Api/AvatarController.php @@ -0,0 +1,263 @@ +redraw(); + + return response(['success' => true]); + } + + public static function GetUserAssets($userId) + { + return UserAsset::where('owner_id', $userId) + ->whereRelation('asset', 'moderated', false) + ->orderByDesc('id'); + } + + public function listAssets(Request $request) + { + $validator = Validator::make($request->all(), [ + 'assetTypeId' => ['required', 'int'] + ]); + + if($validator->fails()) { + return ValidationHelper::generateValidatorError($validator); + } + + $valid = $validator->valid(); + + if(!in_array($valid['assetTypeId'], $this->validAssetTypeIds)) { + $validator->errors()->add('assetTypeId', 'Invalid assetTypeId supplied.'); + return ValidationHelper::generateValidatorError($validator); + } + + $userAssets = self::GetUserAssets(Auth::user()->id) + ->whereRelation('asset', 'assetTypeId', $valid['assetTypeId']) + ->groupBy('asset_id') + ->paginate(12); + $data = []; + + foreach($userAssets as $userAsset) + { + $asset = $userAsset->asset; + + array_push($data, [ + 'id' => $asset->id, + 'Url' => route('shop.asset', ['asset' => $asset, 'assetName' => Str::slug($asset->name, '-')]), + 'Thumbnail' => $asset->getThumbnail(), + 'Name' => $asset->name, + 'Wearing' => Auth::user()->isWearing($asset->id) + ]); + } + + return response([ + 'data' => $data, + 'pages' => ($userAssets->hasPages() ? $userAssets->lastPage() : 1) + ]); + } + + public function listWearing(Request $request) + { + $avatarAssets = AvatarAsset::where('owner_id', Auth::user()->id)->get(); + $data = []; + + foreach($avatarAssets as $avatarAsset) + { + $asset = $avatarAsset->asset; + + array_push($data, [ + 'id' => $asset->id, + 'Url' => route('shop.asset', ['asset' => $asset, 'assetName' => Str::slug($asset->name, '-')]), + 'Thumbnail' => $asset->getThumbnail(), + 'Name' => $asset->name, + 'Wearing' => true + ]); + } + + return response([ + 'data' => $data + ]); + } + + public function wearAsset(Request $request) + { + $validator = Validator::make($request->all(), [ + 'id' => [ + 'required', + Rule::exists('App\Models\Asset', 'id')->where(function($query) { + return $query->where('moderated', false); + }) + ] + ]); + + if($validator->fails()) { + return ValidationHelper::generateValidatorError($validator); + } + + $valid = $validator->valid(); + + $userAsset = self::GetUserAssets(Auth::user()->id) + ->where('asset_id', $valid['id']) + ->first(); + + if(!$userAsset) { + $validator->errors()->add('id', 'User does not own asset.'); + return ValidationHelper::generateValidatorError($validator); + } + + if(Auth::user()->isWearing($valid['id']) && $userAsset->asset->assetTypeId == 8) { // 8 = hat + $validator->errors()->add('id', 'User is already wearing asset.'); + return ValidationHelper::generateValidatorError($validator); + } + + if(!in_array($userAsset->asset->assetTypeId, $this->validAssetTypeIds)) { + $validator->errors()->add('id', 'This asset cannot be worn.'); + return ValidationHelper::generateValidatorError($validator); + } + + $wornItems = AvatarAsset::where('owner_id', Auth::user()->id) + ->whereRelation('asset', 'assetTypeId', $userAsset->asset->assetTypeId); + if($userAsset->asset->assetTypeId != 8 && $wornItems->exists()) // 8 = hat + { + $wornItems->delete(); + } + elseif($userAsset->asset->assetTypeId == 8 && $wornItems->count() >= 10) + { + $validator->errors()->add('id', 'User has hit the wearing limit on this asset type.'); + return ValidationHelper::generateValidatorError($validator); + } + + AvatarAsset::Create([ + 'owner_id' => Auth::user()->id, + 'asset_id' => $valid['id'] + ]); + + Auth::user()->redraw(); + + return response(['success' => true]); + } + + public function removeAsset(Request $request) + { + $validator = Validator::make($request->all(), [ + 'id' => [ + 'required', + Rule::exists('App\Models\Asset', 'id')->where(function($query) { + return $query->where('moderated', false); + }) + ] + ]); + + if($validator->fails()) { + return ValidationHelper::generateValidatorError($validator); + } + + $valid = $validator->valid(); + + if(!Auth::user()->isWearing($valid['id'])) { + $validator->errors()->add('id', 'User is not wearing asset.'); + return ValidationHelper::generateValidatorError($validator); + } + + AvatarAsset::where('owner_id', Auth::user()->id) + ->where('asset_id', $valid['id']) + ->delete(); + + Auth::user()->redraw(); + + return response(['success' => true]); + } + + public function setBodyColor(Request $request) + { + $validator = Validator::make($request->all(), [ + 'part' => ['required', 'regex:/(Head|Torso|LeftArm|RightArm|LeftLeg|RightLeg)/i'], + 'color' => ['required', 'int'] + ]); + + if($validator->fails()) { + return ValidationHelper::generateValidatorError($validator); + } + + $valid = $validator->valid(); + + if(!BrickColorHelper::isValidColor($valid['color'])) { + $validator->errors()->add('color', 'Invalid color id.'); + return ValidationHelper::generateValidatorError($validator); + } + + $part = strtolower($valid['part']); + switch($part) + { + case 'leftarm': + $part = 'leftArm'; + break; + case 'rightarm': + $part = 'rightArm'; + break; + case 'leftleg': + $part = 'leftLeg'; + break; + case 'rightleg': + $part = 'rightLeg'; + break; + } + + $bodyColors = Auth::user()->getBodyColors(); + $bodyColors->{$part} = $valid['color']; + $bodyColors->save(); + + Auth::user()->redraw(); + + return response(['success' => true]); + } + + public function getBodyColors(Request $request) + { + $bodyColors = Auth::user()->getBodyColors(); + + return response([ + 'data' => [ + 'Head' => $bodyColors->head, + 'Torso' => $bodyColors->torso, + 'RightArm' => $bodyColors->rightArm, + 'LeftArm' => $bodyColors->leftArm, + 'RightLeg' => $bodyColors->rightLeg, + 'LeftLeg' => $bodyColors->leftLeg + ] + ]); + } +} diff --git a/web/app/Http/Controllers/Web/Auth/RegisteredUserController.php b/web/app/Http/Controllers/Web/Auth/RegisteredUserController.php index eafe076..b746f7a 100644 --- a/web/app/Http/Controllers/Web/Auth/RegisteredUserController.php +++ b/web/app/Http/Controllers/Web/Auth/RegisteredUserController.php @@ -2,15 +2,19 @@ namespace App\Http\Controllers\Web\Auth; -use App\Models\User; -use App\Providers\RouteServiceProvider; use Illuminate\Auth\Events\Registered; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Validator; use Illuminate\Validation\Rules; + use App\Http\Controllers\Controller; +use App\Models\AvatarAsset; +use App\Models\DefaultUserAsset; +use App\Models\UserAsset; +use App\Models\User; +use App\Providers\RouteServiceProvider; class RegisteredUserController extends Controller { @@ -53,7 +57,22 @@ class RegisteredUserController extends Controller 'email' => $request->email, 'password' => Hash::make($request->password), ]); - + + foreach(DefaultUserAsset::all() as $defaultAsset) + { + UserAsset::createSerialed($user->id, $defaultAsset->asset_id); + + if($defaultAsset->wearing) + { + AvatarAsset::create([ + 'owner_id' => $user->id, + 'asset_id' => $defaultAsset->asset_id + ]); + } + } + + $user->redraw(); + event(new Registered($user)); Auth::login($user); diff --git a/web/app/Http/Controllers/Web/ClientAvatarController.php b/web/app/Http/Controllers/Web/ClientAvatarController.php new file mode 100644 index 0000000..935946a --- /dev/null +++ b/web/app/Http/Controllers/Web/ClientAvatarController.php @@ -0,0 +1,87 @@ +all(), [ + 'userId' => [ + 'required', + Rule::exists('App\Models\User', 'id') + ] + ]); + + if($validator->fails()) { + return ValidationHelper::generateValidatorError($validator); + } + + $valid = $validator->valid(); + $user = User::where('id', $valid['userId'])->first(); + + if($user->hasActivePunishment() && $user->getPunishment()->isDeletion()) { + $validator->errors()->add('id', 'User is moderated.'); + return ValidationHelper::generateValidatorError($validator); + } + + $document = simplexml_load_string(GridHelper::getBodyColorsXML()); + $bodyColors = $user->getBodyColors(); + + $document->xpath('//int[@name="HeadColor"]')[0][0] = $bodyColors->head; + $document->xpath('//int[@name="TorsoColor"]')[0][0] = $bodyColors->torso; + $document->xpath('//int[@name="LeftArmColor"]')[0][0] = $bodyColors->leftArm; + $document->xpath('//int[@name="LeftLegColor"]')[0][0] = $bodyColors->leftLeg; + $document->xpath('//int[@name="RightArmColor"]')[0][0] = $bodyColors->rightArm; + $document->xpath('//int[@name="RightLegColor"]')[0][0] = $bodyColors->rightLeg; + + return response($document->asXML()) + ->header('Content-Type', 'application/xml'); + } + + public function characterFetch(Request $request) + { + $validator = Validator::make($request->all(), [ + 'userId' => [ + 'required', + Rule::exists('App\Models\User', 'id') + ] + ]); + + if($validator->fails()) { + return ValidationHelper::generateValidatorError($validator); + } + + $valid = $validator->valid(); + $user = User::where('id', $valid['userId'])->first(); + + if($user->hasActivePunishment() && $user->getPunishment()->isDeletion()) { + $validator->errors()->add('id', 'User is moderated.'); + return ValidationHelper::generateValidatorError($validator); + } + + $charApp = ''; + $charApp .= route('client.bodyColors', ['userId' => $user->id]); + + foreach($user->getWearing()->get() as $avatarAsset) + { + $charApp .= ';' . route('client.asset', ['id' => $avatarAsset->asset->id]); + + if($avatarAsset->asset->assetTypeId == 19) // Gear + $charApp .= '&equipped=1'; + } + + return response($charApp) + ->header('Content-Type', 'text/plain'); + } +} diff --git a/web/app/Jobs/ArbiterRender.php b/web/app/Jobs/ArbiterRender.php index 8770f3b..9507eef 100644 --- a/web/app/Jobs/ArbiterRender.php +++ b/web/app/Jobs/ArbiterRender.php @@ -100,12 +100,17 @@ class ArbiterRender implements ShouldQueue array_push($arguments, 0); // Camera Offset X array_push($arguments, 0); // Camera Offset Y case 'Avatar': - $arguments[0] = url('test', ['id' => $this->assetId]); // TODO: this + $arguments[0] = route('client.characterFetch', ['userId' => $this->assetId]); break; + case 'Torso': + case 'Right Arm': + case 'Left Arm': + case 'Left Leg': + case 'Right Leg': + $this->type = 'BodyPart'; case 'Head': case 'Shirt': case 'Pants': - case 'BodyPart': // TODO: XlXi: Move this to config, as it could be different from prod in a testing environment. Also move this to it's own asset (not loading from roblox). array_push($arguments, 'https://www.roblox.com/asset/?id=1785197'); // Rig break; diff --git a/web/app/Models/AvatarAsset.php b/web/app/Models/AvatarAsset.php new file mode 100644 index 0000000..aa2b1e0 --- /dev/null +++ b/web/app/Models/AvatarAsset.php @@ -0,0 +1,26 @@ +belongsTo(Asset::class, 'asset_id'); + } +} diff --git a/web/app/Models/AvatarColor.php b/web/app/Models/AvatarColor.php new file mode 100644 index 0000000..100c3f0 --- /dev/null +++ b/web/app/Models/AvatarColor.php @@ -0,0 +1,59 @@ + $userId, + 'head' => $headColor, + 'torso' => $torsoColor, + 'leftArm' => $headColor, + 'rightArm' => $headColor, + 'leftLeg' => 102, + 'rightLeg' => 102 + ]); + } +} diff --git a/web/app/Models/AvatarOutfit.php b/web/app/Models/AvatarOutfit.php new file mode 100644 index 0000000..eff44e2 --- /dev/null +++ b/web/app/Models/AvatarOutfit.php @@ -0,0 +1,11 @@ +save(); } + public function redraw() + { + $oldHashes = [ + $this->thumbnailBustHash, + $this->thumbnail2DHash, + $this->thumbnail3DHash + ]; + + $this->thumbnailBustHash = null; + $this->thumbnail2DHash = null; + $this->thumbnail3DHash = null; + $this->timestamps = false; + $this->save(); + + foreach($oldHashes as $hash) + { + if(!User::where('thumbnailBustHash', $hash)->orWhere('thumbnail2DHash', $hash)->orWhere('thumbnail3DHash', $hash)->exists()) + CdnHelper::Delete($hash); + } + } + + public function isWearing($assetId) + { + return AvatarAsset::where('owner_id', $this->id) + ->where('asset_id', $assetId) + ->exists(); + } + + public function getWearing() + { + return AvatarAsset::where('owner_id', $this->id) + ->whereRelation('asset', 'moderated', 0); + } + + public function getBodyColors() + { + $colors = AvatarColor::user($this->id); + if($colors->exists()) + return $colors->first(); + + return AvatarColor::newForUser($this->id); + } + public function userToJson() { return [ diff --git a/web/config/database.php b/web/config/database.php index fc18290..c5a2a2e 100644 --- a/web/config/database.php +++ b/web/config/database.php @@ -87,6 +87,15 @@ return [ 'prefix' => '', 'prefix_indexes' => true, 'strict' => true, + 'modes' => [ + //'ONLY_FULL_GROUP_BY', + 'STRICT_TRANS_TABLES', + 'NO_ZERO_IN_DATE', + 'NO_ZERO_DATE', + 'ERROR_FOR_DIVISION_BY_ZERO', + 'NO_AUTO_CREATE_USER', + 'NO_ENGINE_SUBSTITUTION' + ], 'engine' => null, 'options' => extension_loaded('pdo_mysql') ? array_filter([ PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), diff --git a/web/database/migrations/2023_01_19_202239_create_avatar_assets_table.php b/web/database/migrations/2023_01_19_202239_create_avatar_assets_table.php new file mode 100644 index 0000000..1a46c43 --- /dev/null +++ b/web/database/migrations/2023_01_19_202239_create_avatar_assets_table.php @@ -0,0 +1,35 @@ +id(); + + $table->unsignedBigInteger('owner_id'); + $table->unsignedBigInteger('asset_id'); + + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('avatar_assets'); + } +}; diff --git a/web/database/migrations/2023_01_20_232605_create_avatar_colors_table.php b/web/database/migrations/2023_01_20_232605_create_avatar_colors_table.php new file mode 100644 index 0000000..0f801b1 --- /dev/null +++ b/web/database/migrations/2023_01_20_232605_create_avatar_colors_table.php @@ -0,0 +1,40 @@ +id(); + + $table->unsignedBigInteger('owner_id')->unique(); + $table->unsignedBigInteger('head'); + $table->unsignedBigInteger('torso'); + $table->unsignedBigInteger('leftArm'); + $table->unsignedBigInteger('rightArm'); + $table->unsignedBigInteger('leftLeg'); + $table->unsignedBigInteger('rightLeg'); + + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('avatar_colors'); + } +}; diff --git a/web/database/migrations/2023_01_20_234149_create_default_user_assets_table.php b/web/database/migrations/2023_01_20_234149_create_default_user_assets_table.php new file mode 100644 index 0000000..34ff121 --- /dev/null +++ b/web/database/migrations/2023_01_20_234149_create_default_user_assets_table.php @@ -0,0 +1,35 @@ +id(); + + $table->unsignedBigInteger('asset_id'); + $table->boolean('wearing'); + + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('default_user_assets'); + } +}; diff --git a/web/database/migrations/2023_01_21_033046_create_avatar_outfits_table.php b/web/database/migrations/2023_01_21_033046_create_avatar_outfits_table.php new file mode 100644 index 0000000..cb1d340 --- /dev/null +++ b/web/database/migrations/2023_01_21_033046_create_avatar_outfits_table.php @@ -0,0 +1,34 @@ +id(); + + $table->unsignedBigInteger('owner_id'); + + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('avatar_outfits'); + } +}; diff --git a/web/database/migrations/2023_01_21_033053_create_avatar_outfit_assets_table.php b/web/database/migrations/2023_01_21_033053_create_avatar_outfit_assets_table.php new file mode 100644 index 0000000..e3460d0 --- /dev/null +++ b/web/database/migrations/2023_01_21_033053_create_avatar_outfit_assets_table.php @@ -0,0 +1,35 @@ +id(); + + $table->unsignedBigInteger('outfit_id'); + $table->unsignedBigInteger('asset_id'); + + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('avatar_outfit_assets'); + } +}; diff --git a/web/resources/js/components/AvatarEditor.js b/web/resources/js/components/AvatarEditor.js new file mode 100644 index 0000000..cea89da --- /dev/null +++ b/web/resources/js/components/AvatarEditor.js @@ -0,0 +1,882 @@ +/* + Copyright © XlXi 2022 +*/ + +import { Component, createRef, createElement } from 'react'; +import axios from 'axios'; + +import classNames from 'classnames/bind'; + +import { buildGenericApiUrl } from '../util/HTTP.js'; +import ProgressiveImage from './ProgressiveImage'; +import Loader from './Loader'; + +import ThumbnailTool from './ThumbnailTool'; + +axios.defaults.withCredentials = true; + +const brickColors = [ + {id: 1, name: 'White'}, + {id: 2, name: 'Grey'}, + {id: 3, name: 'Light yellow'}, + {id: 5, name: 'Brick yellow'}, + {id: 6, name: 'Light green (Mint)'}, + {id: 9, name: 'Light reddish violet'}, + {id: 11, name: 'Pastel Blue'}, + {id: 12, name: 'Light orange brown'}, + {id: 18, name: 'Nougat'}, + {id: 21, name: 'Bright red'}, + {id: 22, name: 'Med. reddish violet'}, + {id: 23, name: 'Bright blue'}, + {id: 24, name: 'Bright yellow'}, + {id: 25, name: 'Earth orange'}, + {id: 26, name: 'Black'}, + {id: 27, name: 'Dark grey'}, + {id: 28, name: 'Dark green'}, + {id: 29, name: 'Medium green'}, + {id: 36, name: 'Lig. Yellowich orange'}, + {id: 37, name: 'Bright green'}, + {id: 38, name: 'Dark orange'}, + {id: 39, name: 'Light bluish violet'}, + {id: 40, name: 'Transparent'}, + {id: 41, name: 'Tr. Red'}, + {id: 42, name: 'Tr. Lg blue'}, + {id: 43, name: 'Tr. Blue'}, + {id: 44, name: 'Tr. Yellow'}, + {id: 45, name: 'Light blue'}, + {id: 47, name: 'Tr. Flu. Reddish orange'}, + {id: 48, name: 'Tr. Green'}, + {id: 49, name: 'Tr. Flu. Green'}, + {id: 50, name: 'Phosph. White'}, + {id: 100, name: 'Light red'}, + {id: 101, name: 'Medium red'}, + {id: 102, name: 'Medium blue'}, + {id: 103, name: 'Light grey'}, + {id: 104, name: 'Bright violet'}, + {id: 105, name: 'Br. yellowish orange'}, + {id: 106, name: 'Bright orange'}, + {id: 107, name: 'Bright bluish green'}, + {id: 108, name: 'Earth yellow'}, + {id: 110, name: 'Bright bluish violet'}, + {id: 111, name: 'Tr. Brown'}, + {id: 112, name: 'Medium bluish violet'}, + {id: 113, name: 'Tr. Medi. reddish violet'}, + {id: 115, name: 'Med. yellowish green'}, + {id: 116, name: 'Med. bluish green'}, + {id: 118, name: 'Light bluish green'}, + {id: 119, name: 'Br. yellowish green'}, + {id: 120, name: 'Lig. yellowish green'}, + {id: 121, name: 'Med. yellowish orange'}, + {id: 123, name: 'Br. reddish orange'}, + {id: 124, name: 'Bright reddish violet'}, + {id: 125, name: 'Light orange'}, + {id: 126, name: 'Tr. Bright bluish violet'}, + {id: 127, name: 'Gold'}, + {id: 128, name: 'Dark nougat'}, + {id: 131, name: 'Silver'}, + {id: 133, name: 'Neon orange'}, + {id: 134, name: 'Neon green'}, + {id: 135, name: 'Sand blue'}, + {id: 136, name: 'Sand violet'}, + {id: 137, name: 'Medium orange'}, + {id: 138, name: 'Sand yellow'}, + {id: 140, name: 'Earth blue'}, + {id: 141, name: 'Earth green'}, + {id: 143, name: 'Tr. Flu. Blue'}, + {id: 145, name: 'Sand blue metallic'}, + {id: 146, name: 'Sand violet metallic'}, + {id: 147, name: 'Sand yellow metallic'}, + {id: 148, name: 'Dark grey metallic'}, + {id: 149, name: 'Black metallic'}, + {id: 150, name: 'Light grey metallic'}, + {id: 151, name: 'Sand green'}, + {id: 153, name: 'Sand red'}, + {id: 154, name: 'Dark red'}, + {id: 157, name: 'Tr. Flu. Yellow'}, + {id: 158, name: 'Tr. Flu. Red'}, + {id: 168, name: 'Gun metallic'}, + {id: 176, name: 'Red flip/flop'}, + {id: 178, name: 'Yellow flip/flop'}, + {id: 179, name: 'Silver flip/flop'}, + {id: 180, name: 'Curry'}, + {id: 190, name: 'Fire Yellow'}, + {id: 191, name: 'Flame yellowish orange'}, + {id: 192, name: 'Reddish brown'}, + {id: 193, name: 'Flame reddish orange'}, + {id: 194, name: 'Medium stone grey'}, + {id: 195, name: 'Royal blue'}, + {id: 196, name: 'Dark Royal blue'}, + {id: 198, name: 'Bright reddish lilac'}, + {id: 199, name: 'Dark stone grey'}, + {id: 200, name: 'Lemon metalic'}, + {id: 208, name: 'Light stone grey'}, + {id: 209, name: 'Dark Curry'}, + {id: 210, name: 'Faded green'}, + {id: 211, name: 'Turquoise'}, + {id: 212, name: 'Light Royal blue'}, + {id: 213, name: 'Medium Royal blue'}, + {id: 216, name: 'Rust'}, + {id: 217, name: 'Brown'}, + {id: 218, name: 'Reddish lilac'}, + {id: 219, name: 'Lilac'}, + {id: 220, name: 'Light lilac'}, + {id: 221, name: 'Bright purple'}, + {id: 222, name: 'Light purple'}, + {id: 223, name: 'Light pink'}, + {id: 224, name: 'Light brick yellow'}, + {id: 225, name: 'Warm yellowish orange'}, + {id: 226, name: 'Cool yellow'}, + {id: 232, name: 'Dove blue'}, + {id: 268, name: 'Medium lilac'}, + {id: 301, name: 'Slime green'}, + {id: 302, name: 'Smoky grey'}, + {id: 303, name: 'Dark blue'}, + {id: 304, name: 'Parsley green'}, + {id: 305, name: 'Steel blue'}, + {id: 306, name: 'Storm blue'}, + {id: 307, name: 'Lapis'}, + {id: 308, name: 'Dark indigo'}, + {id: 309, name: 'Sea green'}, + {id: 310, name: 'Shamrock'}, + {id: 311, name: 'Fossil'}, + {id: 312, name: 'Mulberry'}, + {id: 313, name: 'Forest green'}, + {id: 314, name: 'Cadet blue'}, + {id: 315, name: 'Electric blue'}, + {id: 316, name: 'Eggplant'}, + {id: 317, name: 'Moss'}, + {id: 318, name: 'Artichoke'}, + {id: 319, name: 'Sage green'}, + {id: 320, name: 'Ghost grey'}, + {id: 321, name: 'Lilac'}, + {id: 322, name: 'Plum'}, + {id: 323, name: 'Olivine'}, + {id: 324, name: 'Laurel green'}, + {id: 325, name: 'Quill grey'}, + {id: 327, name: 'Crimson'}, + {id: 328, name: 'Mint'}, + {id: 329, name: 'Baby blue'}, + {id: 330, name: 'Carnation pink'}, + {id: 331, name: 'Persimmon'}, + {id: 332, name: 'Maroon'}, + {id: 333, name: 'Gold'}, + {id: 334, name: 'Daisy orange'}, + {id: 335, name: 'Pearl'}, + {id: 336, name: 'Fog'}, + {id: 337, name: 'Salmon'}, + {id: 338, name: 'Terra Cotta'}, + {id: 339, name: 'Cocoa'}, + {id: 340, name: 'Wheat'}, + {id: 341, name: 'Buttermilk'}, + {id: 342, name: 'Mauve'}, + {id: 343, name: 'Sunrise'}, + {id: 344, name: 'Tawny'}, + {id: 345, name: 'Rust'}, + {id: 346, name: 'Cashmere'}, + {id: 347, name: 'Khaki'}, + {id: 348, name: 'Lily white'}, + {id: 349, name: 'Seashell'}, + {id: 350, name: 'Burgundy'}, + {id: 351, name: 'Cork'}, + {id: 352, name: 'Burlap'}, + {id: 353, name: 'Beige'}, + {id: 354, name: 'Oyster'}, + {id: 355, name: 'Pine Cone'}, + {id: 356, name: 'Fawn brown'}, + {id: 357, name: 'Hurricane grey'}, + {id: 358, name: 'Cloudy grey'}, + {id: 359, name: 'Linen'}, + {id: 360, name: 'Copper'}, + {id: 361, name: 'Dirt brown'}, + {id: 362, name: 'Bronze'}, + {id: 363, name: 'Flint'}, + {id: 364, name: 'Dark taupe'}, + {id: 365, name: 'Burnt Sienna'}, + {id: 1001, name: 'Institutional white'}, + {id: 1002, name: 'Mid gray'}, + {id: 1003, name: 'Really black'}, + {id: 1004, name: 'Really red'}, + {id: 1005, name: 'Deep orange'}, + {id: 1006, name: 'Alder'}, + {id: 1007, name: 'Dusty Rose'}, + {id: 1008, name: 'Olive'}, + {id: 1009, name: 'New Yeller'}, + {id: 1010, name: 'Really blue'}, + {id: 1011, name: 'Navy blue'}, + {id: 1012, name: 'Deep blue'}, + {id: 1013, name: 'Cyan'}, + {id: 1014, name: 'CGA brown'}, + {id: 1015, name: 'Magenta'}, + {id: 1016, name: 'Pink'}, + {id: 1017, name: 'Deep orange'}, + {id: 1018, name: 'Teal'}, + {id: 1019, name: 'Toothpaste'}, + {id: 1020, name: 'Lime green'}, + {id: 1021, name: 'Camo'}, + {id: 1022, name: 'Grime'}, + {id: 1023, name: 'Lavender'}, + {id: 1024, name: 'Pastel light blue'}, + {id: 1025, name: 'Pastel orange'}, + {id: 1026, name: 'Pastel violet'}, + {id: 1027, name: 'Pastel blue-green'}, + {id: 1028, name: 'Pastel green'}, + {id: 1029, name: 'Pastel yellow'}, + {id: 1030, name: 'Pastel brown'}, + {id: 1031, name: 'Royal purple'}, + {id: 1032, name: 'Hot pink'} +]; + +class EditorItemCard extends Component { + constructor(props) { + super(props); + this.state = { + worn: false + }; + + this.wearAssetId = this.wearAssetId.bind(this); + } + + componentDidMount() { + if(this.props.item.Wearing) + this.setState({ worn: true }); + } + + wearAssetId(assetId) { + this.setState({ worn: !this.state.worn }); + if(this.state.worn) + this.props.unwearAssetId(assetId); + else + this.props.wearAssetId(assetId); + } + + render() { + var item = this.props.item; + + return ( +
{ item.Name }
+Nothing found.
+ : +outfits
>); + } +} + +// TODO: XlXi: Move this out of this component. I was too lazy to do it initially but it can be done. +class BodyColorPaneBodyPart extends Component { + constructor(props) { + super(props); + this.state = { + color: 'vb-bc-194' + } + + this.setColor = this.setColor.bind(this); + } + + setColor(color) { + this.setState({ color: color }); + } + + render() { + return ( + + ) + } +} + +class BodyColorSelectionModal extends Component { + constructor(props) { + super(props); + this.state = { + }; + + this.ModalRef = createRef(); + this.Modal = null; + } + + componentDidMount() { + this.Modal = new Bootstrap.Modal(this.ModalRef.current); + this.Modal.show(); + + this.ModalRef.current.addEventListener('hidden.bs.modal', (event) => { + this.props.setModal(null); + }); + + var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="bc-tooltip"]')); + var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) { + return new Bootstrap.Tooltip(tooltipTriggerEl) + }); + } + + componentWillUnmount() { + this.Modal.dispose(); + } + + render() { + return ( +Nothing found.
+ : +Is something wrong with your avatar?
+ Click here to re-draw it! + +Nothing found.
: -Todo:
+