IpCheck.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. <?php
  2. namespace App\Services;
  3. use App\Facade\TableName;
  4. use App\Notification\TelegramBot;
  5. use App\Util;
  6. use Illuminate\Support\Facades\DB;
  7. use Illuminate\Support\Facades\Log;
  8. use Illuminate\Support\Facades\Redis;
  9. class IpCheck
  10. {
  11. public $lastLocation = null;
  12. // 检测是否是巴西IP
  13. public function ipCheck($ip, $PackageName = "com.ouro777.play", $v = 1, $go404 = false)
  14. {
  15. $origin = @$_SERVER['HTTP_HOST'];
  16. $stats = Redis::get("serversOriginStat");
  17. if (!$stats) {
  18. $stats = [];
  19. } else {
  20. $stats = json_decode($stats, true);
  21. }
  22. if (!isset($stats[$origin])) $stats[$origin] = 0;
  23. $stats[$origin]++;
  24. Redis::set('serversOriginStat', json_encode($stats));
  25. $agent = strtolower(@$_SERVER['HTTP_USER_AGENT']);
  26. // $ios = 0;
  27. // if ( strstr( $agent, 'iphone' ) || strstr( $agent, 'ipad' ) ) {
  28. // $ios = 1;
  29. // }
  30. // if($ios){
  31. // }
  32. // return false;
  33. return true;
  34. // split3[0] * 1000000000 + split3[1] * 1000000 + split3[2] * 1000 + parseInt(split3[3]);
  35. $explode = explode('.', $ip);
  36. if (count($explode) < 4) {
  37. return false;
  38. }
  39. $valueN = $explode[0] * 1000000 + $explode[1] * 1000 + (int)$explode[2];
  40. $value = $explode[0] * 1000000000 + $explode[1] * 1000000 + $explode[2] * 1000 + (int)$explode[3];
  41. return true;
  42. //调试加白区
  43. if ($ip == '92.98.30.151') {
  44. return 'BR';
  45. }
  46. //mysg home $valueN==117020154 starhub sg
  47. if ($ip == '116.87.197.194' || $ip == '183.192.138.113' || $ip == '8.222.157.68' || $valueN == 117020154) {
  48. // return "MXX";
  49. return 'BR';
  50. }
  51. if ($ip == '47.237.107.111') {
  52. return 'BR';
  53. }
  54. if ($ip == '172.233.20.45') {
  55. return 'CO';
  56. }
  57. $closeApks = ["com.fortuna.sol.slots", "com.lucky.athena.boa", "com.niubility.pg.tig", "com.lendario.game.slots", "com.glorygame.slotwin", "com.wtmdjsg.hapfun", "com.golden777.redstorm", "iam.thebest.tiger", "com.coins777.ouro", "com.wildwestduals.slot777", "com.wildwestduals.slot888", "com.fortuna.sol.slots", "com.luckygame.ate"];
  58. if (in_array($PackageName, $closeApks)) {
  59. Util::WriteLog('inreview', $this->saveToIpBlack($valueN, $ip, 'close' . $PackageName . "_$v"));
  60. if ($go404) {
  61. http_response_code(404);
  62. exit();
  63. } else {
  64. return 0;
  65. }
  66. }
  67. //针对审核的逻辑
  68. if (Redis::exists("InReview_{$PackageName}")) {
  69. $InReview = Redis::get("InReview_{$PackageName}");
  70. } else {
  71. $app = DB::connection('write')->table('QPPlatformDB.dbo.ChannelPackageName')
  72. ->where('PackageName', $PackageName)->select("InReview")->first();
  73. if (!isset($app) || empty($app)) {
  74. if (!Redis::exists("IpCheck_Error_{$ip}")) {
  75. $result = $this->getIpLocation($ip);
  76. $agent = @$_SERVER['HTTP_USER_AGENT'] ?? "";
  77. $refer = @$_SERVER["HTTP_REFERER"] ?? "";
  78. $locale = @$_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? "";
  79. $url = @$_SERVER['HTTP_HOST'] . @$_SERVER['REQUEST_URI'];
  80. TelegramBot::getDefault()->sendProgramNotify("CheckIP", "$PackageName not found", compact('url', 'locale', 'result', 'agent', 'refer'));
  81. }
  82. Redis::set("IpCheck_Error_{$ip}", $ip);
  83. Redis::expire("IpCheck_Error_{$ip}", 3600);
  84. // $InReview=1;
  85. } else {
  86. $InReview = $app->InReview;
  87. Redis::set("InReview_{$PackageName}", $InReview);
  88. Redis::expire("InReview_{$PackageName}", 3600);
  89. }
  90. }
  91. $InReview = intval($InReview);
  92. if ($InReview == 1 || in_array($PackageName, [])) {
  93. Util::WriteLog('inreview', $this->saveToIpBlack($valueN, $ip, 'review' . $PackageName . "_$v"));
  94. return 0;
  95. }
  96. //特殊号段屏蔽
  97. if (in_array($explode[0] . '.' . $explode[1], ["45.133", "66.102"])) {
  98. Util::WriteLog("ipblocked", $this->saveToIpBlack($valueN, $ip, 'review' . $PackageName . "_$v"));
  99. if ($go404) {
  100. http_response_code(404);
  101. exit();
  102. } else {
  103. return 0;
  104. }
  105. }
  106. //先进行黑名单检查
  107. $blacklist = DB::table(TableName::QPAccountsDB() . 'CheckIPBlack')->where('IP', $valueN)->exists();
  108. if ($blacklist) {
  109. Util::WriteLog("ipblocked", $this->saveToIpBlack($valueN, $ip, 'review' . $PackageName . "_$v"));//compact('valueN','ip','PackageName','v'));
  110. if ($go404) {
  111. http_response_code(404);
  112. exit();
  113. } else {
  114. return false;
  115. }
  116. }
  117. // $mxPackages=["com.game.dream.snake","com.game.dream.snake2","com.secggplcheck.ott","com.west.frzyapp","com.halloween.appwin","com.candle.abyssalapex","com.candlegamesprime.basketball"];
  118. //本地数据库搜索
  119. $result = @DB::table(TableName::QPAccountsDB() . 'CheckIP')->where('IP', $valueN)->select("Country")->first();
  120. $existCountry = $result->Country ?? null;
  121. //判断巴西
  122. if (in_array($existCountry, self::$validCountries)) {
  123. return $existCountry;
  124. }
  125. //{"ip":"45.233.55.215","ip_number":"770258903","ip_version":4,"country_name":"Brazil","country_code2":"BR","isp":"Fox Net Provedor de Acesso Ltda ME","response_code":"200","response_message":"OK"}
  126. //不存在库中开始搜索
  127. $ipsearchs = [];
  128. try {
  129. $result = $this->getIpLocation($ip);
  130. $ipsearchs[] = $result;
  131. //入库
  132. if (isset($result['country_name'])) {
  133. $this->saveToIpDatabase($valueN, $result['country_code2'], $result['isp']);
  134. //m247 必杀
  135. if (strstr($result['isp'], "M247") || strstr($result['isp'], "Google") || strstr($result['isp'], "YouTube") || strstr($result['isp'], "Apple")) {
  136. Util::WriteLog("ipblocked", $this->saveToIpBlack($valueN, $ip, 'm247_' . $PackageName . "_$v"));
  137. return false;
  138. }
  139. if (in_array($result['country_code2'], self::$validCountries)) {
  140. return $result['country_code2'];
  141. } else if (in_array($result['isp'], ['OVH US LLC', 'Oneclick Hosting', 'OVH Hosting Inc.', 'OVH SAS', 'Oracle Corporation'])) {
  142. $this->saveToIpDatabase($valueN, 'BR', $result['isp']);
  143. return 'BR';
  144. }
  145. Log::channel('ip')->info($result);
  146. //手动证明的补充信息
  147. if (in_array($explode[0] . '.' . $explode[1], ["148.78", "15.235", "135.148", "149.56"])) {
  148. $this->saveToIpDatabase($valueN, 'BR', $result['isp']);
  149. //OVH SAS
  150. return 'BR';
  151. }
  152. }
  153. } catch (\Exception $e) {
  154. Log::channel('ip')->info($ip);
  155. Log::channel('ip')->info($e->getMessage());
  156. }
  157. try {
  158. //二叉
  159. $result = $this->iplogger($ip);
  160. $result = $result['result'];
  161. $ipsearchs[] = $result;
  162. if (isset($result['country_name'])) {
  163. $this->saveToIpDatabase($valueN, $result['country'], $result['isp']);
  164. if (strstr($result['isp'], "M247") || strstr($result['isp'], "Google") || strstr($result['isp'], "YouTube")) {
  165. Util::WriteLog("ipblocked", $this->saveToIpBlack($valueN, $ip, 'm247_' . $PackageName . "_$v"));
  166. return false;
  167. }
  168. if (in_array($result['country'], self::$validCountries)) {
  169. return $result['country'];
  170. }
  171. }
  172. } catch (\Exception $e) {
  173. Log::channel('ip')->info($ip);
  174. Log::channel('ip')->info($e->getMessage());
  175. }
  176. if(strstr($PackageName,'com.ouro777.ares')){
  177. return 'BR';
  178. }
  179. Util::WriteLog("ipblocked", $ipsearchs);
  180. //////////////////////////////////////////////////////////////////
  181. //////////////////////////////////////////////////////////////////
  182. // $ipLibrary = config('ipCheck');
  183. // $data = collect(json_decode($ipLibrary, true));
  184. // $r = $data
  185. // ->where('start', '<=', $value)
  186. // ->where('end', '>=', $value)
  187. // ->first();
  188. // if (empty($r)) {
  189. // Util::WriteLog("ipblocked",$ipsearchs);
  190. // return false;
  191. // }else{
  192. // Util::WriteLog("findbyconfig",$ipsearchs);
  193. // }
  194. // Util::WriteLog("ipblocked", $this->saveToIpBlack($valueN, $ip, 'notknow' . $PackageName . "_$v"));
  195. return true;
  196. }
  197. private function saveToIpDatabase($valueN, $countryCode, $isp)
  198. {
  199. DB::table(TableName::QPAccountsDB() . 'CheckIP')->updateOrInsert(['IP' => $valueN], ['IP' => $valueN, 'Country' => strtoupper($countryCode), 'isp' => $isp]);
  200. }
  201. private function saveToIpBlack($valueN, $ip, $reason)
  202. {
  203. $result = $this->getIpLocation($ip);
  204. $agent = @$_SERVER['HTTP_USER_AGENT'] ?? "";
  205. //入库
  206. // DB::table(TableName::QPAccountsDB() . 'CheckIPBlack')->updateOrInsert(['IP' => $valueN], ['IP' => $valueN, 'Country' => strtoupper($result['country_code2']??''), 'isp' => $result['isp']??'', 'reason' => $reason,'date'=>date('Y-m-d H:i:s')]);
  207. $arr = ['IP' => $valueN, 'Country' => strtoupper($result['country_code2'] ?? ''), 'isp' => $result['isp'] ?? '', 'reason' => $reason, 'date' => date('Y-m-d H:i:s'), 'agent' => $agent];
  208. $record = DB::table(TableName::QPAccountsDB() . 'CheckIPBlack')->select("IP", "reason", "agent")->orderByDesc("id")->first();
  209. $record = (array)$record;
  210. if (isset($record) && $record['IP'] == $arr['IP'] && $record['agent'] == $arr['agent'] && $record['reason'] == $arr['reason']) {
  211. } else {
  212. DB::table(TableName::QPAccountsDB() . 'CheckIPBlack')->insert($arr);
  213. }
  214. return $result;
  215. }
  216. /**
  217. * @param $ip
  218. * @return {"result":{"ip":"192.99.235.224","timezone":"America\/Sao_Paulo","offset":"UTC -03:00","localtime":"June 1, 2023 at 5:11 AM","eu":false,"continent":"sa","continent_name":"South America","country":"br","country_name":"Brazil","city":"Inhapim","state":"Minas Gerais","district":"Inhapim","zipcode":"- - -","latitude":-19.5492,"longitude":-42.12,"isp":"OVH Hosting","organization":"OVH SAS","connection":"Corporate","weather_station":"BRXX0568"},"timezone":"Asia\/Shanghai","language":"us","balance":9997}
  219. */
  220. public function iplogger($ip)
  221. {
  222. $ch = curl_init();
  223. curl_setopt($ch, CURLOPT_URL, "https://api.iplogger.org/ip/main/");
  224. curl_setopt($ch, CURLOPT_HTTPHEADER, [
  225. 'X-token: api_0viCf5BdhjzKlZT2E2JywrpbCY1BLJSl',
  226. 'Content-Type: multipart/form-data'
  227. ]);
  228. curl_setopt($ch, CURLOPT_POST, 1);
  229. curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate');
  230. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  231. curl_setopt($ch, CURLOPT_POSTFIELDS, [
  232. 'ip' => $ip
  233. ]);
  234. $res = curl_exec($ch);
  235. curl_close($ch);
  236. $res = trim($res);
  237. // Log::channel('ip')->info('iplogger:'.$res);
  238. $res = \GuzzleHttp\json_decode($res, true);
  239. $this->lastLocation = $res;
  240. return $res;
  241. }
  242. public function getIpLocation($ip)
  243. {
  244. $result = [];
  245. try {
  246. $data = file_get_contents("https://api.iplocation.net/?ip=" . $ip);
  247. $result = \GuzzleHttp\json_decode($data, true);
  248. } catch (\Exception $e) {
  249. Log::channel('ip')->info($ip);
  250. Log::channel('ip')->info($e->getMessage());
  251. }
  252. $this->lastLocation = $result;
  253. return $result;
  254. }
  255. public static function getGeoLocation($ip)
  256. {
  257. $ipcheck = new IpCheck();
  258. $result = $ipcheck->iplogger($ip);
  259. $insert=[];
  260. if (isset($result) && isset($result['isp'])) {
  261. $insert['isp'] = $result['isp'];
  262. $insert['country'] = $result['country'];
  263. $insert['city'] = $result['city'];
  264. } else {
  265. $result = $ipcheck->getIpLocation($ip);
  266. if (isset($result) && isset($result['isp'])) {
  267. $insert['isp'] = $result['isp'];
  268. $insert['country'] = $result['country_code2'];
  269. $insert['city'] = '';
  270. }
  271. }
  272. return $insert;
  273. }
  274. public static $validCountries = ['BR','BD', 'MX', 'CO', 'AR', 'PE', 'CL','PK','US'];
  275. public static $countries = [
  276. 'BD' => [
  277. 'country' => 'Bangladesh',
  278. 'phone_code' => '880',
  279. 'population' => 16400, // 16400万
  280. 'currency_symbol' => '৳',
  281. 'currency_code' => 'BDT',
  282. 'usd_exchange_rate'=> 80,
  283. 'language_code' => 'bn-BD',
  284. 'phone_length' => '10,11'
  285. ],
  286. 'PK' => [
  287. 'country' => 'Pakistan',
  288. 'phone_code' => '92',
  289. 'population' => 23100, // 23100万
  290. 'currency_symbol' => 'Rs',
  291. 'currency_code' => 'PKR',
  292. 'usd_exchange_rate' => 280,
  293. 'language_code' => 'ur-PK',
  294. 'phone_length' => '10,11'
  295. ],
  296. 'US' => [
  297. 'country' => 'United States',
  298. 'phone_code' => '1',
  299. 'population' => 33200, // 33200万
  300. 'currency_symbol' => '$',
  301. 'currency_code' => 'USD',
  302. 'usd_exchange_rate'=> 1,
  303. 'language_code' => 'en-US',
  304. 'phone_length' => '10'
  305. ],
  306. 'BR' => [
  307. 'country' => 'Brazil',
  308. 'phone_code' => '55',
  309. 'population' => 21400, // 21400万
  310. 'currency_symbol' => 'R$',
  311. 'currency_code' => 'BRL',
  312. 'usd_exchange_rate'=> 5,
  313. 'language_code' => 'pt-BR',
  314. 'phone_length' => '10,11'
  315. ],
  316. 'MX' => [
  317. 'country' => 'Mexico',
  318. 'phone_code' => '52',
  319. 'population' => 13000, // 13000万
  320. 'currency_symbol' => 'M$',
  321. 'currency_code' => 'MXN',
  322. 'usd_exchange_rate'=> 18,
  323. 'language_code' => 'es-MX',
  324. 'phone_length' => '10'
  325. ],
  326. 'CO' => [
  327. 'country' => 'Colombia',
  328. 'phone_code' => '57',
  329. 'population' => 5100, // 5100万
  330. 'currency_symbol' => 'COL$',
  331. 'currency_code' => 'COP',
  332. 'usd_exchange_rate'=> 4000,
  333. 'language_code' => 'es-CO',
  334. 'phone_length' => '10'
  335. ],
  336. 'AR' => [
  337. 'country' => 'Argentina',
  338. 'phone_code' => '54',
  339. 'population' => 4500, // 4500万
  340. 'currency_symbol' => '$',
  341. 'currency_code' => 'ARS',
  342. 'usd_exchange_rate'=> 350,
  343. 'language_code' => 'es-AR',
  344. 'phone_length' => '7,10'
  345. ],
  346. 'CA' => [
  347. 'country' => 'Canada',
  348. 'phone_code' => '1',
  349. 'population' => 3800, // 3800万
  350. 'currency_symbol' => 'C$',
  351. 'currency_code' => 'CAD',
  352. 'usd_exchange_rate'=> 1.3,
  353. 'language_code' => 'en-CA',
  354. 'phone_length' => '10'
  355. ],
  356. 'PE' => [
  357. 'country' => 'Peru',
  358. 'phone_code' => '51',
  359. 'population' => 3300, // 3300万
  360. 'currency_symbol' => 'S/.',
  361. 'currency_code' => 'PEN',
  362. 'usd_exchange_rate'=> 4,
  363. 'language_code' => 'es-PE',
  364. 'phone_length' => '9'
  365. ],
  366. 'VE' => [
  367. 'country' => 'Venezuela',
  368. 'phone_code' => '58',
  369. 'population' => 2800, // 2800万
  370. 'currency_symbol' => 'Bs.',
  371. 'currency_code' => 'VES',
  372. 'usd_exchange_rate'=> 25,
  373. 'language_code' => 'es-VE',
  374. 'phone_length' => '10'
  375. ],
  376. 'CL' => [
  377. 'country' => 'Chile',
  378. 'phone_code' => '56',
  379. 'population' => 1900, // 1900万
  380. 'currency_symbol' => '$',
  381. 'currency_code' => 'CLP',
  382. 'usd_exchange_rate'=> 850,
  383. 'language_code' => 'es-CL',
  384. 'phone_length' => '9'
  385. ],
  386. 'GT' => [
  387. 'country' => 'Guatemala',
  388. 'phone_code' => '502',
  389. 'population' => 1800, // 1800万
  390. 'currency_symbol' => 'Q',
  391. 'currency_code' => 'GTQ',
  392. 'usd_exchange_rate'=> 8,
  393. 'language_code' => 'es-GT',
  394. 'phone_length' => '8'
  395. ],
  396. 'EC' => [
  397. 'country' => 'Ecuador',
  398. 'phone_code' => '593',
  399. 'population' => 1800, // 1800万
  400. 'currency_symbol' => '$',
  401. 'currency_code' => 'USD',
  402. 'usd_exchange_rate'=> 1,
  403. 'language_code' => 'es-EC',
  404. 'phone_length' => '9'
  405. ],
  406. 'BO' => [
  407. 'country' => 'Bolivia',
  408. 'phone_code' => '591',
  409. 'population' => 1200, // 1200万
  410. 'currency_symbol' => 'Bs.',
  411. 'currency_code' => 'BOB',
  412. 'usd_exchange_rate'=> 7,
  413. 'language_code' => 'es-BO',
  414. 'phone_length' => '8'
  415. ],
  416. // 添加其他国家的数据...
  417. ];
  418. }