1: | <?php |
2: | /** |
3: | * This file is part of GameQ. |
4: | * |
5: | * GameQ is free software; you can redistribute it and/or modify |
6: | * it under the terms of the GNU Lesser General Public License as published by |
7: | * the Free Software Foundation; either version 3 of the License, or |
8: | * (at your option) any later version. |
9: | * |
10: | * GameQ is distributed in the hope that it will be useful, |
11: | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12: | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13: | * GNU Lesser General Public License for more details. |
14: | * |
15: | * You should have received a copy of the GNU Lesser General Public License |
16: | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
17: | */ |
18: | |
19: | namespace GameQ\Filters; |
20: | |
21: | use Closure; |
22: | use GameQ\Helpers\Arr; |
23: | use GameQ\Server; |
24: | |
25: | /** |
26: | * Class Strip Colors |
27: | * |
28: | * This Filter is responsible for removing |
29: | * color codes from the provided result. |
30: | * |
31: | * @package GameQ\Filters |
32: | */ |
33: | class Stripcolors extends Base |
34: | { |
35: | /** |
36: | * Determines if data should be persisted for unit testing. |
37: | * |
38: | * @var bool |
39: | */ |
40: | protected $writeTestData = false; |
41: | |
42: | /** |
43: | * Apply this filter |
44: | * |
45: | * @SuppressWarnings(PHPMD.CyclomaticComplexity) |
46: | * |
47: | * @param array $result |
48: | * @param \GameQ\Server $server |
49: | * |
50: | * @return array |
51: | */ |
52: | public function apply(array $result, Server $server) |
53: | { |
54: | // Prevent working on empty results |
55: | if (! empty($result)) { |
56: | // Handle unit test data generation |
57: | if ($this->writeTestData) { |
58: | // Initialize potential data for unit testing |
59: | $unitTestData = []; |
60: | |
61: | // Add the initial result to the unit test data |
62: | $unitTestData['raw'][$server->id()] = $result; |
63: | } |
64: | |
65: | // Determine the executor defined for the current Protocol |
66: | if ($executor = $this->getExecutor($server)) { |
67: | // Apply the executor to the result recursively |
68: | $result = Arr::recursively($result, function (&$value) use ($executor) { |
69: | // The executor may only be applied to strings |
70: | if (is_string($value)) { |
71: | // Strip the colors and update the value by reference |
72: | $value = $executor($value); |
73: | } elseif (! is_array($value)) { |
74: | $value = (string) $value; // TODO: Remove this in the next major version. |
75: | } |
76: | }); |
77: | } |
78: | |
79: | // Handle unit test data generation |
80: | if ($this->writeTestData) { |
81: | // Add the filtered result to the unit test data |
82: | $unitTestData['filtered'][$server->id()] = $result; |
83: | |
84: | // Persist the collected data to the tests directory |
85: | file_put_contents( |
86: | sprintf( |
87: | '%s/../../../tests/Filters/Providers/Stripcolors\%s_1.json', |
88: | __DIR__, |
89: | $server->protocol()->getProtocol() |
90: | ), |
91: | json_encode($unitTestData, JSON_UNESCAPED_UNICODE | JSON_PARTIAL_OUTPUT_ON_ERROR) |
92: | ); |
93: | } |
94: | } |
95: | |
96: | // Return the filtered result |
97: | return $result; |
98: | } |
99: | |
100: | /** |
101: | * Strip color codes from quake based games. |
102: | * |
103: | * @param string $string |
104: | */ |
105: | protected function stripQuake($string) |
106: | { |
107: | return preg_replace('#(\^.)#', '', $string); |
108: | } |
109: | |
110: | /** |
111: | * Strip color codes from Source based games. |
112: | * |
113: | * @param string $string |
114: | */ |
115: | protected function stripSource($string) |
116: | { |
117: | return strip_tags($string); |
118: | } |
119: | |
120: | /** |
121: | * Strip color codes from Unreal based games. |
122: | * |
123: | * @param string $string |
124: | */ |
125: | protected function stripUnreal($string) |
126: | { |
127: | return preg_replace('/\x1b.../', '', $string); |
128: | } |
129: | |
130: | /** |
131: | * This helper determines the correct executor to |
132: | * be used with the current Protocl instance. |
133: | * |
134: | * @SuppressWarnings(PHPMD.CyclomaticComplexity) |
135: | * |
136: | * @return null|Closure<string> |
137: | */ |
138: | protected function getExecutor(Server $server) |
139: | { |
140: | // Determine the correct executor for the current Protocol instance |
141: | switch ($server->protocol()->getProtocol()) { |
142: | // Strip Protocols using Quake color tags |
143: | case 'quake2': |
144: | case 'quake3': |
145: | case 'doom3': |
146: | case 'gta5m': |
147: | return [$this, 'stripQuake']; |
148: | |
149: | // Strip Protocols using Unreal color tags |
150: | case 'unreal2': |
151: | case 'ut3': |
152: | case 'gamespy3': // not sure if gamespy3 supports ut colors but won't hurt |
153: | case 'gamespy2': |
154: | return [$this, 'stripUnreal']; |
155: | |
156: | // Strip Protocols using Source color tags |
157: | case 'source': |
158: | return [$this, 'stripSource']; |
159: | |
160: | default: |
161: | return null; |
162: | } |
163: | } |
164: | } |
165: |