index.html 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0">
  6. <title>巨龙之戒-经典冒险主公闯关开局</title>
  7. <script src="./js/jquery.min.js"></script>
  8. <style>
  9. * {
  10. margin: 0;
  11. padding: 0;
  12. border: 0;
  13. box-sizing: border-box;
  14. }
  15. body {
  16. padding-top: 60px;
  17. background-color: #000;
  18. font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  19. }
  20. img {
  21. display: block;
  22. width: 100%;
  23. }
  24. a {
  25. text-decoration: none;
  26. }
  27. #content-wrapper {
  28. background-color: #fff;
  29. max-width: 750px;
  30. margin: 0 auto;
  31. overflow: hidden;
  32. }
  33. #top-banner {
  34. position: fixed;
  35. top: 0;
  36. width: 100%;
  37. height: 60px;
  38. background: rgba(0, 0, 0, 0.8);
  39. display: flex;
  40. align-items: center;
  41. justify-content: space-between;
  42. padding: 0 20px;
  43. max-width: 750px;
  44. z-index: 100;
  45. }
  46. .btn {
  47. display: inline-block;
  48. color: #fff;
  49. font-size: 20px;
  50. background-color: #f64e4e;
  51. border-radius: 15px;
  52. padding: 5px 20px;
  53. cursor: pointer;
  54. }
  55. /* Modal Styles */
  56. .modal-overlay {
  57. display: none;
  58. position: fixed;
  59. top: 0;
  60. left: 0;
  61. width: 100%;
  62. height: 100%;
  63. background: rgba(0, 0, 0, 0.6);
  64. backdrop-filter: blur(5px);
  65. z-index: 1000;
  66. align-items: center;
  67. justify-content: center;
  68. }
  69. .modal-content {
  70. width: 90%;
  71. max-width: 320px;
  72. background: #f5f7f8;
  73. border-radius: 20px;
  74. overflow: hidden;
  75. box-shadow: 0 10px 25px rgba(0,0,0,0.3);
  76. animation: modalFadeIn 0.3s ease-out;
  77. }
  78. @keyframes modalFadeIn {
  79. from { opacity: 0; transform: scale(0.9); }
  80. to { opacity: 1; transform: scale(1); }
  81. }
  82. .modal-header {
  83. padding: 20px;
  84. text-align: center;
  85. border-bottom: 1px solid #eee;
  86. }
  87. .modal-header h2 {
  88. font-size: 20px;
  89. color: #333;
  90. }
  91. .modal-body {
  92. padding: 20px;
  93. }
  94. .form-group {
  95. margin-bottom: 15px;
  96. }
  97. .form-input {
  98. width: 100%;
  99. height: 45px;
  100. padding: 0 15px;
  101. border: 1px solid #ddd;
  102. border-radius: 10px;
  103. font-size: 14px;
  104. outline: none;
  105. }
  106. .form-input:focus {
  107. border-color: #f64e4e;
  108. }
  109. .captcha-group {
  110. display: flex;
  111. gap: 10px;
  112. }
  113. .btn-captcha {
  114. height: 45px;
  115. padding: 0 10px;
  116. background: #eee;
  117. border-radius: 10px;
  118. font-size: 13px;
  119. color: #666;
  120. cursor: pointer;
  121. white-space: nowrap;
  122. }
  123. .btn-login {
  124. width: 100%;
  125. height: 45px;
  126. background: #f64e4e;
  127. color: #fff;
  128. border-radius: 10px;
  129. font-size: 16px;
  130. font-weight: bold;
  131. cursor: pointer;
  132. margin-top: 10px;
  133. }
  134. .privacy-text {
  135. font-size: 10px;
  136. color: #999;
  137. text-align: center;
  138. margin-top: 15px;
  139. line-height: 1.4;
  140. }
  141. .close-btn {
  142. position: absolute;
  143. top: 10px;
  144. right: 15px;
  145. font-size: 24px;
  146. color: #999;
  147. cursor: pointer;
  148. }
  149. /* WeChat Tip Styles */
  150. #weixin-tip {
  151. position: fixed;
  152. left: 0;
  153. top: 0;
  154. background: rgba(0, 0, 0, 0.8);
  155. width: 100%;
  156. height: 100%;
  157. z-index: 2000;
  158. display: none;
  159. }
  160. #weixin-tip p {
  161. text-align: center;
  162. margin-top: 10%;
  163. padding: 0 5%;
  164. }
  165. .wechat-img {
  166. max-width: 100%;
  167. height: auto;
  168. }
  169. /* Toast Styles */
  170. .total-toast {
  171. position: fixed;
  172. top: 50%;
  173. left: 50%;
  174. transform: translate(-50%, -50%);
  175. background: rgba(0, 0, 0, 0.7);
  176. color: #fff;
  177. padding: 12px 24px;
  178. border-radius: 8px;
  179. font-size: 14px;
  180. z-index: 9999;
  181. text-align: center;
  182. pointer-events: none;
  183. display: none;
  184. max-width: 80%;
  185. word-wrap: break-word;
  186. }
  187. </style>
  188. </head>
  189. <body>
  190. <div id="content-wrapper">
  191. <div id="top-banner">
  192. <div style="display: flex;align-items: center;justify-content: center;">
  193. <img src="./assets/icon.png" style="width: 50px;">
  194. <span style="color: #fff;font-size: 25px;">巨龙之戒</span>
  195. </div>
  196. <a class="btn btn-download" style="justify-self: end;">开始游戏</a>
  197. </div>
  198. <a class="btn-download"><img src="./assets/1.gif"></a>
  199. <a class="btn-download"><img src="./assets/2.gif"></a>
  200. <a class="btn-download"><img src="./assets/3.gif"></a>
  201. </div>
  202. <!-- Login Modal -->
  203. <div id="loginModal" class="modal-overlay">
  204. <div class="modal-content" style="position: relative;">
  205. <span class="close-btn" onclick="closeModal()">&times;</span>
  206. <div class="modal-header">
  207. <h2>游戏登录</h2>
  208. </div>
  209. <div class="modal-body">
  210. <div class="form-group">
  211. <input type="tel" id="phone" class="form-input" placeholder="请输入手机号">
  212. </div>
  213. <div class="form-group captcha-group">
  214. <input type="text" id="captcha" class="form-input" placeholder="请输入验证码">
  215. <button type="button" class="btn-captcha" id="getCaptcha">获取验证码</button>
  216. </div>
  217. <button type="button" class="btn-login" id="loginBtn">登录并进入游戏</button>
  218. </div>
  219. </div>
  220. </div>
  221. <div id="weixin-tip">
  222. <p><img src="./assets/live_weixin.png" alt="微信打开" class="wechat-img"/></p>
  223. </div>
  224. <script src="./js/md5.min.js"></script>
  225. <script>
  226. function getUrlParam(name, defaultValue = '') {
  227. const urlParams = new URLSearchParams(window.location.search);
  228. return urlParams.get(name) || defaultValue;
  229. }
  230. const API_URL = 'https://app.hainanruiyu.cn/landingpage/index.php';
  231. const APP_ID = parseInt(getUrlParam('appid', ''));
  232. const APP_KEY = 'b995721db94fa9b206fab7ef687a13d3';
  233. const MEDIA_ID = getUrlParam('media_id', '');
  234. function is_weixin() {
  235. var ua = navigator.userAgent.toLowerCase();
  236. return ua.indexOf('micromessenger') !== -1;
  237. }
  238. const DOWNLOAD_LINKS = {
  239. ios: 'https://apps.apple.com/cn/app/id6746466555',
  240. android: 'https://apps.apple.com/cn/app/id6746466555', // 这里以后可以替换为安卓下载包地址
  241. default: 'https://apps.apple.com/cn/app/id6746466555'
  242. };
  243. const modal = document.getElementById('loginModal');
  244. const loginBtn = document.getElementById('loginBtn');
  245. const getCaptchaBtn = document.getElementById('getCaptcha');
  246. let pendingUrl = '';
  247. let sessionId = '';
  248. function total(msg) {
  249. $('.total-toast').remove();
  250. const toast = $('<div class="total-toast">' + msg + '</div>');
  251. $('body').append(toast);
  252. toast.fadeIn(300).delay(2000).fadeOut(300, function() {
  253. $(this).remove();
  254. });
  255. }
  256. function getBrowserID() {
  257. let id = localStorage.getItem('browser_unique_id');
  258. if (!id) {
  259. id = 'br_' + Math.random().toString(36).substr(2, 9) + Date.now().toString(36);
  260. localStorage.setItem('browser_unique_id', id);
  261. }
  262. return id;
  263. }
  264. const IMEI = getBrowserID();
  265. // 当前投放只针对IOS, 这里默认都是ios
  266. function getOS() {
  267. // const ua = navigator.userAgent;
  268. // if (/iPad|iPhone|iPod/.test(ua)) return 'ios';
  269. // if (/Android/.test(ua)) return 'android';
  270. // return 'pc';
  271. return 'ios'
  272. }
  273. function makeSign(time) {
  274. return md5(APP_KEY + time);
  275. }
  276. function openModal(url) {
  277. // 如果按钮没有 href 或者 href 为空,则根据系统自动分配下载链接
  278. pendingUrl = url || DOWNLOAD_LINKS[getOS()] || DOWNLOAD_LINKS.default;
  279. modal.style.display = 'flex';
  280. }
  281. function closeModal() {
  282. modal.style.display = 'none';
  283. }
  284. // Intercept download clicks
  285. document.querySelectorAll('.btn-download').forEach(link => {
  286. link.addEventListener('click', function(e) {
  287. e.preventDefault();
  288. if (is_weixin()) {
  289. document.getElementById('weixin-tip').style.display = 'block';
  290. } else {
  291. openModal(this.getAttribute('href'));
  292. }
  293. });
  294. });
  295. // Close WeChat tip on click
  296. document.getElementById('weixin-tip').addEventListener('click', function() {
  297. this.style.display = 'none';
  298. });
  299. function sendVerificationCode() {
  300. const phone = document.getElementById('phone').value;
  301. const os = getOS() === 'ios' ? 'ios' : 'android';
  302. if (!/^1[3-9]\d{9}$/.test(phone)) {
  303. total('请输入正确的手机号');
  304. return;
  305. }
  306. getCaptchaBtn.disabled = true;
  307. let count = 60;
  308. const originalText = getCaptchaBtn.innerText;
  309. getCaptchaBtn.innerText = count + 's';
  310. const timer = setInterval(() => {
  311. count--;
  312. if (count <= 0) {
  313. clearInterval(timer);
  314. getCaptchaBtn.disabled = false;
  315. getCaptchaBtn.innerText = '获取验证码';
  316. } else {
  317. getCaptchaBtn.innerText = count + 's';
  318. }
  319. }, 1000);
  320. const time = Math.floor(Date.now() / 1000);
  321. $.ajax({
  322. url: API_URL,
  323. type: 'POST',
  324. contentType: 'application/json',
  325. data: JSON.stringify({
  326. do: 'send_code',
  327. appid: APP_ID,
  328. time: time,
  329. sign: makeSign(time),
  330. phone: phone,
  331. media_id: MEDIA_ID,
  332. os: os,
  333. imei: IMEI
  334. }),
  335. success: function(res) {
  336. let result = typeof res === 'string' ? JSON.parse(res) : res;
  337. console.log(result)
  338. if (result && result.ret == 1) {
  339. sessionId = result.sessionid;
  340. total('验证码已发送');
  341. } else {
  342. total(result.msg || '发送失败,请稍后重试');
  343. clearInterval(timer);
  344. getCaptchaBtn.disabled = false;
  345. getCaptchaBtn.innerText = '获取验证码';
  346. }
  347. },
  348. error: function() {
  349. total('发送失败,网络错误');
  350. clearInterval(timer);
  351. getCaptchaBtn.disabled = false;
  352. getCaptchaBtn.innerText = '获取验证码';
  353. }
  354. });
  355. }
  356. getCaptchaBtn.addEventListener('click', function() {
  357. sendVerificationCode();
  358. });
  359. function executeLogin() {
  360. const phone = document.getElementById('phone').value;
  361. const code = document.getElementById('captcha').value;
  362. const os = getOS() === 'ios' ? 'ios' : 'android';
  363. if (!phone || !code) {
  364. total('请填写手机号和验证码');
  365. return;
  366. }
  367. loginBtn.innerText = '登录中...';
  368. loginBtn.disabled = true;
  369. const time = Math.floor(Date.now() / 1000);
  370. const url = sessionId ? `${API_URL}?phpsessid=${sessionId}` : API_URL;
  371. $.ajax({
  372. url: url,
  373. type: 'POST',
  374. contentType: 'application/json',
  375. data: JSON.stringify({
  376. do: 'register',
  377. appid: APP_ID,
  378. time: time,
  379. sign: makeSign(time),
  380. phone: phone,
  381. code: code,
  382. media_id: MEDIA_ID,
  383. os: os,
  384. imei: IMEI
  385. }),
  386. success: function(res) {
  387. let result = typeof res === 'string' ? JSON.parse(res) : res;
  388. console.log(result)
  389. if (result && result.ret == 1) {
  390. closeModal();
  391. if (MEDIA_ID) {
  392. const reportUrl = `https://tj.hainanruiyu.cn/api/cps.php?c=${MEDIA_ID}`;
  393. $.get(reportUrl).always(function() {
  394. window.location.href = pendingUrl;
  395. });
  396. } else {
  397. window.location.href = pendingUrl;
  398. }
  399. } else {
  400. total(result.msg || '登录失败,请重试');
  401. loginBtn.innerText = '登录并进入游戏';
  402. loginBtn.disabled = false;
  403. }
  404. },
  405. error: function() {
  406. total('登录失败,网络错误');
  407. loginBtn.innerText = '登录并进入游戏';
  408. loginBtn.disabled = false;
  409. }
  410. });
  411. }
  412. loginBtn.addEventListener('click', function() {
  413. if (!this.disabled) {
  414. executeLogin();
  415. }
  416. });
  417. window.addEventListener('click', (e) => {
  418. if (e.target === modal) {
  419. closeModal();
  420. }
  421. });
  422. </script>
  423. </body>
  424. </html>