Repository: Koileo/ticket_for_allcpp Branch: main Commit: c37c2d65c71a Files: 10 Total size: 19.3 KB Directory structure: gitextract_k9dgtw2k/ ├── .github/ │ └── workflows/ │ └── release.yml ├── .gitignore ├── LICENSE ├── README.md ├── config.txt ├── cookie.txt ├── main.py ├── requirements.txt ├── ticket_for_allcpp.spec └── timentp.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/workflows/release.yml ================================================ name: Python Release on: push: tags: - 'v*' jobs: Windows-amd64: permissions: write-all runs-on: windows-latest name: Build Windows Binary steps: - name: Checkout uses: actions/checkout@v4 - name: Init Python 3.12 uses: actions/setup-python@v4 with: python-version: '3.12' cache: 'pip' - name: Install Dependent Packages run: | python -m pip install --upgrade pip pip install wheel pyinstaller pip install -r requirements.txt shell: pwsh - name: Pyinstaller run: | pyinstaller ticket_for_allcpp.spec shell: pwsh - name: Upload Windows File uses: actions/upload-artifact@v3 with: name: ticket_for_allcpp-windows-amd64 path: dist/ticket_for_allcpp.exe Linux-amd64: permissions: write-all runs-on: ubuntu-latest name: Build Linux Amd64 steps: - name: Checkout uses: actions/checkout@v4 - name: Init Python 3.12 uses: actions/setup-python@v4 with: python-version: '3.12' cache: 'pip' - name: Install Dependent Packages run: | python -m pip install --upgrade pip pip install wheel pyinstaller pip install -r requirements.txt - name: Pyinstaller run: | pyinstaller ticket_for_allcpp.spec mv dist/ticket_for_allcpp dist/ticket_for_allcpp-linux-amd64 - name: Upload Linux File uses: actions/upload-artifact@v3 with: name: ticket_for_allcpp-linux-amd64 path: dist/ticket_for_allcpp-linux-amd64 macos-amd64: permissions: write-all runs-on: macOS-latest name: Build macOS Amd64 steps: - name: Checkout uses: actions/checkout@v4 - name: Init Python 3.12 uses: actions/setup-python@v4 with: python-version: '3.12' cache: 'pip' - name: Install Dependent Packages run: | python -m pip install --upgrade pip pip install wheel pyinstaller pip install -r requirements.txt - name: Pyinstaller run: | pyinstaller ticket_for_allcpp.spec mv dist/ticket_for_allcpp dist/ticket_for_allcpp-macos-amd64 - name: Upload macOS File uses: actions/upload-artifact@v3 with: name: ticket_for_allcpp-macos-amd64 path: dist/ticket_for_allcpp-macos-amd64 Create-release: permissions: write-all runs-on: ubuntu-latest needs: [ Windows-amd64, Linux-amd64, macos-amd64] steps: - uses: actions/checkout@v4 - name: Download Artifact uses: actions/download-artifact@v3 - name: get release_informations shell: bash run: | mkdir releases mv ./ticket_for_allcpp-macos-amd64/ticket_for_allcpp-macos-amd64 ./releases/ticket_for_allcpp-macos-amd64 mv ./ticket_for_allcpp-linux-amd64/ticket_for_allcpp-linux-amd64 ./releases/ticket_for_allcpp-linux-amd64 mv ./ticket_for_allcpp-windows-amd64/ticket_for_allcpp.exe ./releases/ticket_for_allcpp-windows-amd64.exe cp config.txt ./releases/config.txt cp cookie.txt ./releases/cookie.txt - name: Create Release id: create_release uses: actions/create-release@latest env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: ${{ github.ref }} release_name: ${{ github.ref }} draft: false prerelease: false - name: Upload Release Asset uses: dwenegar/upload-release-assets@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: release_id: ${{ steps.create_release.outputs.id }} assets_path: | ./releases/ ================================================ FILE: .gitignore ================================================ build/ dist/ ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2024 Koileo Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # ticket_for_allcpp 开源免费,简单易用,多线程暴力 CPP 抢票工具。 > [!NOTE] > 本程序仅供学习交流, 不得用于商业用途 > 使用本程序进行违法操作产生的法律责任由操作者自行承担 > 本次cp30最好使用b站会员购进行抢票,cp30有可能加入验证码,由于之前从未出现,我没办法在开票前保证程序可用性!!!!! ## 安装教程 ### 1. 快速安装 前往 [Releases](https://github.com/Koileo/ticket_for_allcpp/releases) 下载最新可执行文件直接命令行运行。 ### 2. 源码运行 ```shell git clone https://github.com/Koileo/ticket_for_allcpp.git cd ticket_for_allcpp pip install -r requirements.txt python main.py ``` ## 使用说明 ### cookie.txt 配置 - 第一行为账号`cookie`值,浏览器登入CPP直接F12获取并全部复制即可。 - 第二行为`ticketid`,同样也是F12查看 https://www.allcpp.cn/allcpp/ticket/getTicketTypeList.do?eventMainId=xxxx 的响应 一般为4位数字 - 以此类推,第三行第四行也是这样 ### config.txt 配置文件:包括ntp服务器,间隔时长,线程数 - 本程序支持多线程,多账户(默认三线程)。 - 默认实名票全部按照购票人设置数量购买,你绑定几个人买几份票,即默认全选 - 同一账号支持同时购买不同票类,在第二行用“,"分开 ## 其他可用脚本 | 链接 | 主要特色 | | --------------------------------------------------------- | ---------------------- | | https://github.com/mikumifa/cppTickerBuy |图形化,对小白友好 | ## 未来功能 - [ ] 微信通知 - [x] 程序外部配置空隔时间和线程数 - [x] Linux 和 MacOS 打包 - [x] 时间校准 ## 项目问题 反馈程序BUG或者提新功能建议:[点此链接向项目提出反馈BUG](https://github.com/Koileo/ticket_for_allcpp/issues) ## Star History [![Star History Chart](https://api.star-history.com/svg?repos=Koileo/ticket_for_allcpp&type=Date)](https://star-history.com/#Koileo/ticket_for_allcpp&Date) ================================================ FILE: config.txt ================================================ [time] ntp = ntp.aliyun.com [ticket] sleep = 1 num_thread = 3 ================================================ FILE: cookie.txt ================================================ 你的cookie ticketid ================================================ FILE: main.py ================================================ # coding=utf-8 import requests import json import threading import time import secrets import string import hashlib import ntplib import configparser # 定义一个全局锁用于线程同步 thread_dict = {} cookie_file_path = 'cookie.txt' config_file_path = 'config.txt' headers = { 'authority': 'www.allcpp.cn', 'accept': 'application/json, text/plain, */*', 'accept-language': 'zh-CN,zh;q=0.9', 'content-type': 'application/json;charset=UTF-8', 'origin': 'https://cp.allcpp.cn', 'referer': 'https://cp.allcpp.cn/', 'sec-ch-ua': '"Chromium";v="116", "Not)A;Brand";v="24", "Google Chrome";v="116"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"Windows"', 'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'same-site', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36', } # 读取配置文件 def getConfig(filename, section, option): conf = configparser.ConfigParser() conf.read(filename) config = conf.get(section, option) return config def timeconvey(ntp): chec = ntplib.NTPClient() response = chec.request(ntp) timestamp = response.tx_time timestamp_local = time.time() #print(timestamp_local) #print(timestamp) differ= timestamp - timestamp_local return differ def sign_for_post(ticketid): timestamp = str(int(time.time())) ##"1682074579" ## 貌似并不校验 sign: a()(t + r + i + e + n) # nonce="jcFFFK4pPz2eNGBND3xDxTEyZ7PGCyzm" ## 32位随机值即可 n = string.ascii_letters + string.digits nonce = ''.join(secrets.choice(n) for i in range(32)) sign=hashlib.md5(f"2x052A0A1u222{timestamp}{nonce}{ticketid}2sFRs".encode('utf-8')).hexdigest() # print(f"ticket_type_id={ticket_type_id}") # print(f"nonce={nonce}") # print(f"timestamp={timestamp}") # print(f"sign={sign}") vital='nonce='+nonce+'&timeStamp='+timestamp+'&sign='+sign return vital def cookie_string_to_dict(cookie_string): cookies = {} cookie_pairs = cookie_string.split("; ") for pair in cookie_pairs: key, value = pair.split("=", 1) cookies[key] = value return cookies def read_cookies_and_tickets_from_file(): cookies = [] ticket_id = [] ticket_ids = [] try: with open(cookie_file_path, 'r',encoding='utf-8') as file: lines = file.readlines() i = 0 while i < len(lines): cookies.append(lines[i].strip()) # 使用append方法将元素添加到列表 i += 1 if i < len(lines): ticket_id.append(lines[i].strip()) # 使用append方法将元素添加到列表 i += 1 except FileNotFoundError: print(f"File '{cookie_file_path}' not found.") for item in ticket_id: # 使用逗号分割字符串并添加到输出列表 ticket_ids.append(item.split(',')) return cookies, ticket_ids # 返回两个列表作为一个元组 def getpurser(cookie_str): cookies = cookie_string_to_dict(cookie_str) pur = requests.get( url='https://www.allcpp.cn/allcpp/user/purchaser/getList.do', cookies=cookies, headers=headers, ) purrer = pur.content.decode("utf-8") purrer_data = json.loads(purrer) return purrer_data def check_success(cookies,ticketid): url = 'https://www.allcpp.cn/allcpp/user/getMyOrderList.do?pageindex=1&pagesize=10&enabled=0&orderby=0' list = requests.get( url=url, cookies=cookies, headers=headers, ) listing = list.content.decode("utf-8") data = json.loads(listing) # 遍历订单信息 for order in data['result']['list']: if order['ticketTypeId'] == ticketid: return True else: return False def process_thread(ticketid,cookie_str): try: cookies = cookie_string_to_dict(cookie_str) try: pur = requests.get( url='https://www.allcpp.cn/allcpp/user/purchaser/getList.do', cookies=cookies, headers=headers, ) purrer = pur.content.decode("utf-8") purrer_data = json.loads(purrer) print(purrer_data) except json.decoder.JSONDecodeError as e: pass ids = [str(item["id"]) for item in purrer_data] ids_str = ",".join(ids) id_count = len(ids) print(f"IDs for ticket {ticketid}: {ids_str}") json_data = {} retn_params = sign_for_post(ticketid) url = 'https://www.allcpp.cn/allcpp/ticket/buyTicketAliWapPay.do?ticketTypeId=' + str(ticketid) + '&count=' + str( id_count) + '&' + retn_params + '&purchaserIds=' + ids_str print(url) try: response = requests.post( url=url, cookies=cookies, headers=headers, json=json_data, ) resp = response.content.decode("utf-8") parsed_resp = json.loads(resp) except json.decoder.JSONDecodeError as e: pass print(parsed_resp) except: pass i = 0 if parsed_resp.get("isSuccess") == True: print(f"Thread for ticket {ticketid} succeeded") with open(f"output_ticket_{ticketid}_{ids_str}.txt", "a") as output_file: output_file.write(resp) print(f"Thread for ticket {ticketid} with cookies {cookies} succeeded, closing other two threads of the same type.") threads =[] threads_to_close = [thread for thread in threads if thread._target == process_thread and thread._args[0] == ticketid and thread._args[1] == cookies] for thread_to_close in threads_to_close[:2]: # 关闭同类型的前两个线程 thread_to_close.join() return True else: while i < 2: try: with open(f"output_ticket_{ticketid}_{ids_str}_attempt_{i}.txt", "a") as output_file: output_file.write(resp) retn_params = sign_for_post(ticketid) url = 'https://www.allcpp.cn/allcpp/ticket/buyTicketAliWapPay.do?ticketTypeId=' + str(ticketid) + '&count=' + str( id_count) + '&' + retn_params +'&purchaserIds=' + ids_str print(url) try: response = requests.post( url=url, cookies=cookies, headers=headers, json=json_data, ) resp = response.content.decode("utf-8") parsed_resp = json.loads(resp) except json.decoder.JSONDecodeError as e: pass print(parsed_resp) is_success = parsed_resp["isSuccess"] if is_success == True: i = 3 print(f"Thread for ticket {ticketid} succeeded") with open(f"output_ticket_{ticketid}_{ids_str}.txt", "a") as output_file: output_file.write(resp) threads_to_close = [thread for thread in threads if thread._target == process_thread and thread._args[0] == ticketid and thread._args[1] == cookies] for thread_to_close in threads_to_close[:2]: # 关闭同类型的前两个线程 thread_to_close.join() return True else: with open(f"output_ticket_{ticketid}_{ids_str}_attempt.txt", "a") as output_file: output_file.write(resp) url = 'https://www.allcpp.cn/allcpp/ticket/buyTicketAliWapPay.do?ticketTypeId=' + str(ticketid) + '&count=' + str( id_count) + '&' + retn_params +'&purchaserIds=' + ids_str print(url) try: response = requests.post( url=url, cookies=cookies, headers=headers, json=json_data, ) resp = response.content.decode("utf-8") parsed_resp = json.loads(resp) is_success = parsed_resp["isSuccess"] except json.decoder.JSONDecodeError as e: pass if is_success == True: i = 3 print(f"Thread for ticket {ticketid} succeeded") with open(f"output_ticket_{ticketid}_{ids_str}.txt", "a") as output_file: output_file.write(resp) threads_to_close = [thread for thread in threads if thread._target == process_thread and thread._args[0] == ticketid and thread._args[1] == cookies] for thread_to_close in threads_to_close[:2]: # 关闭同类型的前两个线程 thread_to_close.join() return True else: with open(f"output_ticket_{ticketid}_{ids_str}_attempt.txt", "a") as output_file: output_file.write(resp) print(resp) print(type(resp)) time.sleep(sleep_time) except: pass def start(cookies, ticket_ids): thread_dict = {} for i in range(len(cookies)): for j in range(len(ticket_ids[i])): for _ in range(num_thread): ticket = ticket_ids[i][j] cook = cookies[i] thread = threading.Thread(target=process_thread, args=(ticket, cook)) thread.start() def schedule_script_at_timestamp(target_timestamp_ms,cookies, ticket_ids): current_timestamp_ms = int(time.time() * 1000) time_difference_ms = target_timestamp_ms - current_timestamp_ms if time_difference_ms <= 0: print("时间已经过去了主人") else: print(f"还有 {time_difference_ms / 1000} 秒喵~.") def delayed_execution(): time.sleep(time_difference_ms / 1000) start(cookies, ticket_ids) t = threading.Thread(target=delayed_execution) t.start() def main(): ntp = getConfig("config.txt", 'time', 'ntp') global sleep_time sleep_time = float(getConfig("config.txt", 'ticket', 'sleep')) global num_thread num_thread = int(getConfig("config.txt", 'ticket', 'num_thread')) differ = timeconvey(ntp) if differ > 0 : print(f"\033[1;31;47m主人你的时间慢了{abs(differ)}秒\033[0m") print("\033[1;31;47m主人你的时间滞后了哦,请同步时间\033[0m") else: print(f"\033[1;31;47m主人你的时间快了{abs(differ)}秒\033[0m") cookies, ticket_ids = read_cookies_and_tickets_from_file() print(ticket_ids) i=0 while i