First Commit
This commit is contained in:
commit
0d7f152317
55
.dockerignore
Normal file
55
.dockerignore
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
# Git
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
# Python
|
||||||
|
__pycache__
|
||||||
|
*.pyc
|
||||||
|
*.pyo
|
||||||
|
*.pyd
|
||||||
|
.Python
|
||||||
|
env
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
.tox
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
*.log
|
||||||
|
.git
|
||||||
|
.mypy_cache
|
||||||
|
.pytest_cache
|
||||||
|
.hypothesis
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
.DS_Store?
|
||||||
|
._*
|
||||||
|
.Spotlight-V100
|
||||||
|
.Trashes
|
||||||
|
ehthumbs.db
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode
|
||||||
|
.idea
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# Docker
|
||||||
|
Dockerfile*
|
||||||
|
docker-compose*.yml
|
||||||
|
.dockerignore
|
||||||
|
|
||||||
|
# Documentation
|
||||||
|
README.md
|
||||||
|
*.md
|
||||||
|
|
||||||
|
# Other
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
__pycache__
|
||||||
|
.DS_Store
|
||||||
20
Dockerfile.api
Normal file
20
Dockerfile.api
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
FROM python:3.9-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN apt-get update
|
||||||
|
|
||||||
|
COPY requirements.txt .
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
# Copy application files
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Set environment variables
|
||||||
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
|
# Expose port
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
# Run the API server
|
||||||
|
CMD ["python", "cm_api.py"]
|
||||||
17
Dockerfile.telegram
Normal file
17
Dockerfile.telegram
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
FROM python:3.9-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN apt-get update
|
||||||
|
|
||||||
|
COPY requirements.txt .
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
# Copy application files
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Set environment variables
|
||||||
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
|
# Run the telegram bot
|
||||||
|
CMD ["python", "cm_telegram.py"]
|
||||||
17
Dockerfile.transfer
Normal file
17
Dockerfile.transfer
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
FROM python:3.9-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN apt-get update
|
||||||
|
|
||||||
|
COPY requirements.txt .
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
# Copy application files
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Set environment variables
|
||||||
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
|
# Run the API server
|
||||||
|
CMD ["python", "cm_transfer_credit.py"]
|
||||||
20
Dockerfile.web
Normal file
20
Dockerfile.web
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
FROM python:3.9-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN apt-get update
|
||||||
|
|
||||||
|
COPY requirements.txt .
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
# Copy application files
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Set environment variables
|
||||||
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
|
# Expose port
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
# Run the web view
|
||||||
|
CMD ["python", "cm_web_view.py"]
|
||||||
191
cm_api.py
Normal file
191
cm_api.py
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
import threading
|
||||||
|
from flask import Flask, jsonify, request
|
||||||
|
from flask_cors import CORS
|
||||||
|
from db import DB
|
||||||
|
|
||||||
|
|
||||||
|
class CM_API:
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.app = Flask(__name__)
|
||||||
|
CORS(self.app)
|
||||||
|
self._register_routes()
|
||||||
|
|
||||||
|
def _get_database_connection(self):
|
||||||
|
"""Create a new database connection for use"""
|
||||||
|
try:
|
||||||
|
db = DB()
|
||||||
|
return db
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Database connection failed: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _close_database_connection(self, db):
|
||||||
|
"""Close database connection if it exists"""
|
||||||
|
if db is not None:
|
||||||
|
try:
|
||||||
|
# Assuming DB class has a close method or similar cleanup
|
||||||
|
if hasattr(db, 'close'):
|
||||||
|
db.close()
|
||||||
|
elif hasattr(db, 'connection') and hasattr(db.connection, 'close'):
|
||||||
|
db.connection.close()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error closing database connection: {e}")
|
||||||
|
|
||||||
|
def _register_routes(self):
|
||||||
|
# Account routes
|
||||||
|
self.app.route('/acc/<username>', methods=['GET'])(self.get_account)
|
||||||
|
self.app.route('/acc/', methods=['GET'])(self.get_account)
|
||||||
|
|
||||||
|
# User routes
|
||||||
|
self.app.route('/user/<username>', methods=['GET'])(self.get_user)
|
||||||
|
self.app.route('/user/', methods=['GET'])(self.get_user)
|
||||||
|
|
||||||
|
# Update routes
|
||||||
|
self.app.route('/update-acc-data', methods=['POST'])(self.update_acc_data)
|
||||||
|
self.app.route('/update-user-data', methods=['POST'])(self.update_user_data)
|
||||||
|
|
||||||
|
def _check_database_available(self):
|
||||||
|
db = self._get_database_connection()
|
||||||
|
if db is None:
|
||||||
|
return False, None, ("Database not available", 500)
|
||||||
|
return True, db, None
|
||||||
|
|
||||||
|
def _handle_error(self, error, message="An error occurred"):
|
||||||
|
print(f"Error: {error}")
|
||||||
|
return message, 500
|
||||||
|
|
||||||
|
def get_account(self, username=None):
|
||||||
|
is_available, db, error_response = self._check_database_available()
|
||||||
|
if not is_available:
|
||||||
|
return error_response
|
||||||
|
|
||||||
|
try:
|
||||||
|
if username:
|
||||||
|
query = "SELECT username, password, status, link FROM acc WHERE username = %s"
|
||||||
|
query_params = [username]
|
||||||
|
else:
|
||||||
|
query = "SELECT username, password, status, link FROM acc"
|
||||||
|
query_params = []
|
||||||
|
|
||||||
|
results = db.query(query, query_params)
|
||||||
|
return jsonify(results)
|
||||||
|
|
||||||
|
except Exception as error:
|
||||||
|
return self._handle_error(error, "Not Found"), 404
|
||||||
|
finally:
|
||||||
|
self._close_database_connection(db)
|
||||||
|
|
||||||
|
def get_user(self, username=None):
|
||||||
|
is_available, db, error_response = self._check_database_available()
|
||||||
|
if not is_available:
|
||||||
|
return error_response
|
||||||
|
|
||||||
|
try:
|
||||||
|
if username:
|
||||||
|
query = "SELECT f_username, f_password, t_username, t_password FROM user WHERE f_username = %s"
|
||||||
|
query_params = [username]
|
||||||
|
else:
|
||||||
|
query = "SELECT f_username, f_password, t_username, t_password, last_update_time FROM user"
|
||||||
|
query_params = []
|
||||||
|
|
||||||
|
results = db.query(query, query_params)
|
||||||
|
return jsonify(results)
|
||||||
|
|
||||||
|
except Exception as error:
|
||||||
|
return self._handle_error(error, "Not Found"), 404
|
||||||
|
finally:
|
||||||
|
self._close_database_connection(db)
|
||||||
|
|
||||||
|
def update_acc_data(self):
|
||||||
|
is_available, db, error_response = self._check_database_available()
|
||||||
|
if not is_available:
|
||||||
|
return error_response
|
||||||
|
|
||||||
|
try:
|
||||||
|
data = request.get_json()
|
||||||
|
username = data.get('username')
|
||||||
|
password = data.get('password')
|
||||||
|
status = data.get('status')
|
||||||
|
link = data.get('link')
|
||||||
|
|
||||||
|
if not username:
|
||||||
|
return jsonify({"error": "Username is required"})
|
||||||
|
|
||||||
|
result = db.execute(
|
||||||
|
"UPDATE acc SET password = %s, status = %s, link = %s WHERE username = %s",
|
||||||
|
[password, status, link, username]
|
||||||
|
)
|
||||||
|
|
||||||
|
if result:
|
||||||
|
return jsonify("Data updated successfully")
|
||||||
|
else:
|
||||||
|
return jsonify("Error updating data")
|
||||||
|
|
||||||
|
except Exception as error:
|
||||||
|
return self._handle_error(error, "Error updating data"), 500
|
||||||
|
finally:
|
||||||
|
self._close_database_connection(db)
|
||||||
|
|
||||||
|
def update_user_data(self):
|
||||||
|
is_available, db, error_response = self._check_database_available()
|
||||||
|
if not is_available:
|
||||||
|
return error_response
|
||||||
|
|
||||||
|
try:
|
||||||
|
data = request.get_json()
|
||||||
|
f_username = data.get('f_username')
|
||||||
|
f_password = data.get('f_password')
|
||||||
|
t_username = data.get('t_username')
|
||||||
|
t_password = data.get('t_password')
|
||||||
|
|
||||||
|
if not f_username:
|
||||||
|
return jsonify({"error": "f_username is required"})
|
||||||
|
|
||||||
|
result = db.execute(
|
||||||
|
"UPDATE user SET f_password = %s, t_password = %s, t_username = %s, last_update_time = CURRENT_TIMESTAMP WHERE f_username = %s",
|
||||||
|
[f_password, t_password, t_username, f_username]
|
||||||
|
)
|
||||||
|
|
||||||
|
if result:
|
||||||
|
return jsonify("Data updated successfully")
|
||||||
|
else:
|
||||||
|
return jsonify("Error updating data")
|
||||||
|
|
||||||
|
except Exception as error:
|
||||||
|
return self._handle_error(error, "Error updating data")
|
||||||
|
finally:
|
||||||
|
self._close_database_connection(db)
|
||||||
|
|
||||||
|
def run(self, port=3000, debug=True):
|
||||||
|
# Test database connection before starting server
|
||||||
|
test_db = self._get_database_connection()
|
||||||
|
if test_db is None:
|
||||||
|
print("Cannot start server: Database not available")
|
||||||
|
exit(1)
|
||||||
|
self._close_database_connection(test_db)
|
||||||
|
|
||||||
|
print(f'CM Bot DB API Listening at Port : {port}')
|
||||||
|
self.app.run(host='0.0.0.0', port=port, debug=debug)
|
||||||
|
|
||||||
|
def run_in_thread(self, port=3000, debug=False):
|
||||||
|
"""Run the Flask app in a separate thread"""
|
||||||
|
# Test database connection before starting server
|
||||||
|
test_db = self._get_database_connection()
|
||||||
|
if test_db is None:
|
||||||
|
print("Cannot start server: Database not available")
|
||||||
|
return None
|
||||||
|
self._close_database_connection(test_db)
|
||||||
|
|
||||||
|
def run_app():
|
||||||
|
print(f'CM Bot DB API Listening at Port : {port}')
|
||||||
|
self.app.run(host='0.0.0.0', port=port, debug=debug, use_reloader=False)
|
||||||
|
|
||||||
|
thread = threading.Thread(target=run_app, daemon=True)
|
||||||
|
thread.start()
|
||||||
|
return thread
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
api = CM_API()
|
||||||
|
api.run(port = 3000)
|
||||||
499
cm_bot.py
Normal file
499
cm_bot.py
Normal file
@ -0,0 +1,499 @@
|
|||||||
|
import requests, re
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
|
||||||
|
# with open('security_response.html', 'wb') as f:
|
||||||
|
# f.write(response.content)
|
||||||
|
|
||||||
|
class CM_BOT:
|
||||||
|
def __init__(self):
|
||||||
|
self.session = requests.Session()
|
||||||
|
self.base_url = 'https://cm99.net'
|
||||||
|
self.is_logged_in = False
|
||||||
|
self._setup_headers()
|
||||||
|
|
||||||
|
def _setup_headers(self):
|
||||||
|
"""Set up default headers for requests."""
|
||||||
|
|
||||||
|
self.login_headers = {
|
||||||
|
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
|
||||||
|
'accept-encoding': 'identity',
|
||||||
|
'accept-language': 'en-GB,en;q=0.8',
|
||||||
|
'cache-control': 'max-age=0',
|
||||||
|
'content-type': 'application/x-www-form-urlencoded',
|
||||||
|
'origin': self.base_url,
|
||||||
|
'referer': f'{self.base_url}/cm/login',
|
||||||
|
'sec-ch-ua': '"Not;A=Brand";v="99", "Brave";v="139", "Chromium";v="139"',
|
||||||
|
'sec-ch-ua-mobile': '?0',
|
||||||
|
'sec-ch-ua-platform': '"macOS"',
|
||||||
|
'sec-fetch-dest': 'document',
|
||||||
|
'sec-fetch-mode': 'navigate',
|
||||||
|
'sec-fetch-site': 'same-origin',
|
||||||
|
'sec-fetch-user': '?1',
|
||||||
|
'sec-gpc': '1',
|
||||||
|
'upgrade-insecure-requests': '1',
|
||||||
|
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36'
|
||||||
|
}
|
||||||
|
|
||||||
|
self.get_user_tree_headers = {
|
||||||
|
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
|
||||||
|
'accept-encoding': 'identity',
|
||||||
|
'accept-language': 'en-GB,en;q=0.8',
|
||||||
|
'priority': 'u=0, i',
|
||||||
|
'sec-ch-ua': '"Not;A=Brand";v="99", "Brave";v="139", "Chromium";v="139"',
|
||||||
|
'sec-ch-ua-mobile': '?0',
|
||||||
|
'sec-ch-ua-platform': '"macOS"',
|
||||||
|
'sec-fetch-dest': 'document',
|
||||||
|
'sec-fetch-mode': 'navigate',
|
||||||
|
'sec-fetch-site': 'none',
|
||||||
|
'sec-fetch-user': '?1',
|
||||||
|
'sec-gpc': '1',
|
||||||
|
'upgrade-insecure-requests': '1',
|
||||||
|
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36'
|
||||||
|
}
|
||||||
|
|
||||||
|
self.get_register_form_headers = {
|
||||||
|
'accept': 'text/html, */*; q=0.01',
|
||||||
|
'accept-encoding': 'identity',
|
||||||
|
'accept-language': 'en-GB,en;q=0.8',
|
||||||
|
'content-length': '0',
|
||||||
|
'origin': self.base_url,
|
||||||
|
'priority': 'u=1, i',
|
||||||
|
'referer': f'{self.base_url}/cm/userMainAction',
|
||||||
|
'sec-ch-ua': '"Not;A=Brand";v="99", "Brave";v="139", "Chromium";v="139"',
|
||||||
|
'sec-ch-ua-mobile': '?0',
|
||||||
|
'sec-ch-ua-platform': '"macOS"',
|
||||||
|
'sec-fetch-dest': 'empty',
|
||||||
|
'sec-fetch-mode': 'cors',
|
||||||
|
'sec-fetch-site': 'same-origin',
|
||||||
|
'sec-gpc': '1',
|
||||||
|
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36',
|
||||||
|
'x-requested-with': 'XMLHttpRequest'
|
||||||
|
}
|
||||||
|
|
||||||
|
self.get_user_credit_headers = {
|
||||||
|
'accept': 'text/html, */*; q=0.01',
|
||||||
|
'accept-encoding': 'identity',
|
||||||
|
'accept-language': 'en-GB,en;q=0.7',
|
||||||
|
'content-length': '0',
|
||||||
|
'origin': self.base_url,
|
||||||
|
'priority': 'u=1, i',
|
||||||
|
'referer': f'{self.base_url}/cm/mainMenu',
|
||||||
|
'sec-ch-ua': '"Chromium";v="140", "Not=A?Brand";v="24", "Brave";v="140"',
|
||||||
|
'sec-ch-ua-mobile': '?0',
|
||||||
|
'sec-ch-ua-platform': '"macOS"',
|
||||||
|
'sec-fetch-dest': 'empty',
|
||||||
|
'sec-fetch-mode': 'cors',
|
||||||
|
'sec-fetch-site': 'same-origin',
|
||||||
|
'sec-gpc': '1',
|
||||||
|
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36',
|
||||||
|
'x-requested-with': 'XMLHttpRequest'
|
||||||
|
}
|
||||||
|
|
||||||
|
# self.change_pass_headers = {
|
||||||
|
# 'accept': '*/*',
|
||||||
|
# 'accept-encoding': 'identity',
|
||||||
|
# 'accept-language': 'en-GB,en;q=0.8',
|
||||||
|
# 'content-length': '889',
|
||||||
|
# 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
||||||
|
# 'origin': self.base_url,
|
||||||
|
# 'priority': 'u=1, i',
|
||||||
|
# 'referer': f'{self.base_url}/cm/userMainAction',
|
||||||
|
# 'sec-ch-ua': '"Not;A=Brand";v="99", "Brave";v="139", "Chromium";v="139"',
|
||||||
|
# 'sec-ch-ua-mobile': '?0',
|
||||||
|
# 'sec-ch-ua-platform': '"macOS"',
|
||||||
|
# 'sec-fetch-dest': 'empty',
|
||||||
|
# 'sec-fetch-mode': 'cors',
|
||||||
|
# 'sec-fetch-site': 'same-origin',
|
||||||
|
# 'sec-gpc': '1',
|
||||||
|
# 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36',
|
||||||
|
# 'x-requested-with': 'XMLHttpRequest'
|
||||||
|
# }
|
||||||
|
|
||||||
|
self.register_form_headers = {
|
||||||
|
'accept': '*/*',
|
||||||
|
'accept-encoding': 'identity',
|
||||||
|
'accept-language': 'en-GB,en;q=0.8',
|
||||||
|
'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
||||||
|
'origin': self.base_url,
|
||||||
|
'priority': 'u=1, i',
|
||||||
|
'referer': f'{self.base_url}/cm/userMainAction',
|
||||||
|
'sec-ch-ua': '"Not;A=Brand";v="99", "Brave";v="139", "Chromium";v="139"',
|
||||||
|
'sec-ch-ua-mobile': '?0',
|
||||||
|
'sec-ch-ua-platform': '"macOS"',
|
||||||
|
'sec-fetch-dest': 'empty',
|
||||||
|
'sec-fetch-mode': 'cors',
|
||||||
|
'sec-fetch-site': 'same-origin',
|
||||||
|
'sec-gpc': '1',
|
||||||
|
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36',
|
||||||
|
'x-requested-with': 'XMLHttpRequest'
|
||||||
|
}
|
||||||
|
|
||||||
|
self.set_security_pin_headers = {
|
||||||
|
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
|
||||||
|
'accept-encoding': 'identity',
|
||||||
|
'accept-language': 'en-GB,en;q=0.9',
|
||||||
|
'cache-control': 'max-age=0',
|
||||||
|
'content-length': '103',
|
||||||
|
'content-type': 'application/x-www-form-urlencoded',
|
||||||
|
'origin': self.base_url,
|
||||||
|
'priority': 'u=0, i',
|
||||||
|
'referer': f'{self.base_url}/cm/setSecurityPin',
|
||||||
|
'sec-ch-ua': '"Chromium";v="140", "Not=A?Brand";v="24", "Brave";v="140"',
|
||||||
|
'sec-ch-ua-mobile': '?0',
|
||||||
|
'sec-ch-ua-platform': '"macOS"',
|
||||||
|
'sec-fetch-dest': 'document',
|
||||||
|
'sec-fetch-mode': 'navigate',
|
||||||
|
'sec-fetch-site': 'same-origin',
|
||||||
|
'sec-fetch-user': '?1',
|
||||||
|
'sec-gpc': '1',
|
||||||
|
'upgrade-insecure-requests': '1',
|
||||||
|
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36'
|
||||||
|
}
|
||||||
|
|
||||||
|
self.transfer_search_headers = {
|
||||||
|
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
|
||||||
|
'accept-encoding': 'identity',
|
||||||
|
'accept-language': 'en-GB,en;q=0.7',
|
||||||
|
'cache-control': 'max-age=0',
|
||||||
|
'content-length': '78',
|
||||||
|
'content-type': 'application/x-www-form-urlencoded',
|
||||||
|
'origin': self.base_url,
|
||||||
|
'priority': 'u=0, i',
|
||||||
|
'referer': f'{self.base_url}/cm/transfer',
|
||||||
|
'sec-ch-ua': '"Chromium";v="140", "Not=A?Brand";v="24", "Brave";v="140"',
|
||||||
|
'sec-ch-ua-mobile': '?0',
|
||||||
|
'sec-ch-ua-platform': '"macOS"',
|
||||||
|
'sec-fetch-dest': 'document',
|
||||||
|
'sec-fetch-mode': 'navigate',
|
||||||
|
'sec-fetch-site': 'same-origin',
|
||||||
|
'sec-fetch-user': '?1',
|
||||||
|
'sec-gpc': '1',
|
||||||
|
'upgrade-insecure-requests': '1',
|
||||||
|
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36'
|
||||||
|
}
|
||||||
|
|
||||||
|
self.transfer_credit_headers = {
|
||||||
|
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
|
||||||
|
'accept-encoding': 'identity',
|
||||||
|
'accept-language': 'en-GB,en;q=0.7',
|
||||||
|
'cache-control': 'max-age=0',
|
||||||
|
'content-length': '152',
|
||||||
|
'content-type': 'application/x-www-form-urlencoded',
|
||||||
|
'origin': self.base_url,
|
||||||
|
'priority': 'u=0, i',
|
||||||
|
'referer': f'{self.base_url}/cm/searchTransferUser',
|
||||||
|
'sec-ch-ua': '"Chromium";v="140", "Not=A?Brand";v="24", "Brave";v="140"',
|
||||||
|
'sec-ch-ua-mobile': '?0',
|
||||||
|
'sec-ch-ua-platform': '"macOS"',
|
||||||
|
'sec-fetch-dest': 'document',
|
||||||
|
'sec-fetch-mode': 'navigate',
|
||||||
|
'sec-fetch-site': 'same-origin',
|
||||||
|
'sec-fetch-user': '?1',
|
||||||
|
'sec-gpc': '1',
|
||||||
|
'upgrade-insecure-requests': '1',
|
||||||
|
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36'
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_register_data(self, token: str, username: str, password: str):
|
||||||
|
return {
|
||||||
|
'struts.token.name': 'token',
|
||||||
|
'token': f'{token}',
|
||||||
|
'userIsNew': 'true',
|
||||||
|
'searchContent': '',
|
||||||
|
'user.username': f'{username}',
|
||||||
|
'user.companyId': '1',
|
||||||
|
'user.userRoleId': '4',
|
||||||
|
'user.password': f'{password}',
|
||||||
|
'user.confirmPassword': f'{password}',
|
||||||
|
'user.name': f'{username}',
|
||||||
|
'user.mobileNumber': '',
|
||||||
|
'user.email': '',
|
||||||
|
'user.remarks': '',
|
||||||
|
'user.accountStatus': 'A',
|
||||||
|
'user.currencyMYR': 'true',
|
||||||
|
'__checkbox_user.currencyMYR': 'true',
|
||||||
|
'user.allowBetHl': 'true',
|
||||||
|
'__checkbox_user.allowBetHl': 'true',
|
||||||
|
'user.commission3d4d': '5.00',
|
||||||
|
'user.commission5d6d': '5.00',
|
||||||
|
'user.commissionHL': '19.00',
|
||||||
|
'user.commissionHL6d': '19.00',
|
||||||
|
'user.commissionNL': '19.00',
|
||||||
|
'user.commissionNL6d': '19.00',
|
||||||
|
'checkAllPrizePackages': 'on',
|
||||||
|
'selectedPrizePackageList': ['6', '1', '5', '3'],
|
||||||
|
'__multiselect_selectedPrizePackageList': '',
|
||||||
|
'checkAllPrizePackages5D6D': 'on',
|
||||||
|
'selectedPrizePackage5D6DList': '2',
|
||||||
|
'__multiselect_selectedPrizePackage5D6DList': ''
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_security_pin_data(self, token: str, security_pin: str):
|
||||||
|
return {
|
||||||
|
'struts.token.name': 'token',
|
||||||
|
'token': token,
|
||||||
|
'newPin': security_pin,
|
||||||
|
'confirmNewPin': security_pin
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_transfer_search_data(self, token: str, username: str):
|
||||||
|
return {
|
||||||
|
'struts.token.name': 'token',
|
||||||
|
'token': token,
|
||||||
|
'username': username
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_transfer_data(self, token: str, username: str, name: str, toUserId: str, amount: float, security_pin: str):
|
||||||
|
return {
|
||||||
|
'struts.token.name': 'token',
|
||||||
|
'token': token,
|
||||||
|
'username': username,
|
||||||
|
'name': name,
|
||||||
|
'toUserId': toUserId,
|
||||||
|
'amount': amount,
|
||||||
|
'securityPin': security_pin
|
||||||
|
}
|
||||||
|
|
||||||
|
# def get_change_pass_data(self, token: str, user_encrypted_id: str, username: str, password: str):
|
||||||
|
# return {
|
||||||
|
# 'struts.token.name': 'token',
|
||||||
|
# 'token': f'{token}',
|
||||||
|
# 'searchContent': '',
|
||||||
|
# 'userIsNew': 'false',
|
||||||
|
# 'user.encryptedId': f'{user_encrypted_id}',
|
||||||
|
# 'user.username': f'{username}',
|
||||||
|
# 'user.parentId': '31308',
|
||||||
|
# 'user.companyId': '1',
|
||||||
|
# 'user.userRoleId': '4',
|
||||||
|
# 'user.password': f'{password}',
|
||||||
|
# 'user.confirmPassword': f'{password}',
|
||||||
|
# 'user.name': f'{username}',
|
||||||
|
# 'user.mobileNumber': '',
|
||||||
|
# 'user.email': '',
|
||||||
|
# 'user.remarks': '',
|
||||||
|
# 'user.accountStatus': 'A',
|
||||||
|
# 'user.currencyMYR': 'true',
|
||||||
|
# '__checkbox_user.currencyMYR': 'true',
|
||||||
|
# 'user.allowBetHl': 'true',
|
||||||
|
# '__checkbox_user.allowBetHl': 'true',
|
||||||
|
# 'user.balance': '1',
|
||||||
|
# 'user.outstanding': '1',
|
||||||
|
# 'user.commission3d4d': '5.00',
|
||||||
|
# 'user.commission5d6d': '5.00',
|
||||||
|
# 'user.commissionHL': '19.00',
|
||||||
|
# 'user.commissionHL6d': '19.00',
|
||||||
|
# 'user.commissionNL': '19.00',
|
||||||
|
# 'user.commissionNL6d': '19.00',
|
||||||
|
# 'selectedPrizePackageList': ['6', '1', '5', '3'],
|
||||||
|
# '__multiselect_selectedPrizePackageList': '',
|
||||||
|
# 'selectedPrizePackage5D6DList': '2',
|
||||||
|
# '__multiselect_selectedPrizePackage5D6DList': ''
|
||||||
|
# }
|
||||||
|
|
||||||
|
def login(self, username: str, password: str):
|
||||||
|
try:
|
||||||
|
print("Starting login process...")
|
||||||
|
login_page = self.session.get(f'{self.base_url}/cm/login')
|
||||||
|
print(f"Login page status: {login_page.status_code}")
|
||||||
|
|
||||||
|
login_data = {
|
||||||
|
'j_username': username,
|
||||||
|
'j_password': password
|
||||||
|
}
|
||||||
|
|
||||||
|
login_response = self.session.post(
|
||||||
|
f'{self.base_url}/cm/j_security_check',
|
||||||
|
data=login_data,
|
||||||
|
headers=self.login_headers,
|
||||||
|
allow_redirects=True
|
||||||
|
)
|
||||||
|
|
||||||
|
if login_response.status_code == 200 and 'login' not in login_response.url.lower():
|
||||||
|
print("Login successful!")
|
||||||
|
self.is_logged_in = True
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print("Login failed!")
|
||||||
|
self.is_logged_in = False
|
||||||
|
return False
|
||||||
|
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
print(f"Error during login: {e}")
|
||||||
|
self.is_logged_in = False
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_max_user_in_pattern(self, prefix_pattern: str = '13c'):
|
||||||
|
response = self.session.get(f'{self.base_url}/cm/json/generateUserTree?id=0')
|
||||||
|
regex = f'\\[{prefix_pattern}\\d+]'
|
||||||
|
matches = re.findall(regex, response.text)
|
||||||
|
last_match_text = matches[-1]
|
||||||
|
number_part = last_match_text.replace(f"[{prefix_pattern}", "").replace("]", "")
|
||||||
|
last_match = int(number_part)
|
||||||
|
return last_match
|
||||||
|
|
||||||
|
def get_register_form_token(self):
|
||||||
|
try:
|
||||||
|
response = self.session.post(
|
||||||
|
f'{self.base_url}/cm/loadUserAccount',
|
||||||
|
headers=self.get_register_form_headers
|
||||||
|
)
|
||||||
|
soup = BeautifulSoup(response.content, 'html.parser')
|
||||||
|
return soup.find('input', {'name' : "token"})['value']
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
print(f"Error getting register form: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def get_security_pin_form_token(self):
|
||||||
|
response = self.session.get(f'{self.base_url}/cm/setSecurityPin')
|
||||||
|
soup = BeautifulSoup(response.content, 'html.parser')
|
||||||
|
return soup.find('input', {'name' : "token"})['value']
|
||||||
|
|
||||||
|
def register_user(self, user_id, user_password):
|
||||||
|
try:
|
||||||
|
print("Creating user account...")
|
||||||
|
token = self.get_register_form_token()
|
||||||
|
print(f"Token: {token}")
|
||||||
|
|
||||||
|
user_data = self.get_register_data(token, user_id, user_password)
|
||||||
|
print(user_data)
|
||||||
|
response = self.session.post(
|
||||||
|
f'{self.base_url}/cm/saveUserAccount',
|
||||||
|
data=user_data,
|
||||||
|
headers=self.register_form_headers
|
||||||
|
)
|
||||||
|
|
||||||
|
if re.search('User created successfully', response.text):
|
||||||
|
print(f"User account: {user_id} password: {user_password} creation completed!")
|
||||||
|
else:
|
||||||
|
print(f"User account: {user_id} creation FAIL!")
|
||||||
|
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
print(f"Error creating user account: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
# def change_user_password(self, user_id: str, new_user_pass: str):
|
||||||
|
# try:
|
||||||
|
# print(f"Changing user: {user_id} password...")
|
||||||
|
# self.login(self.username, self.password)
|
||||||
|
# token = self.get_register_form_token()
|
||||||
|
# headers = self.change_pass_headers
|
||||||
|
|
||||||
|
# user_data = self.get_change_pass_data(token, )
|
||||||
|
# response = self.session.post(
|
||||||
|
# f'{self.base_url}/cm/saveUserAccount',
|
||||||
|
# data=user_data,
|
||||||
|
# headrs=headers
|
||||||
|
# )
|
||||||
|
|
||||||
|
# except requests.exceptions.RequestException as e:
|
||||||
|
# print(f"Error change user password: {e}")
|
||||||
|
# return None
|
||||||
|
|
||||||
|
def get_register_link(self):
|
||||||
|
response = self.session.get(f"{self.base_url}/cm/showQrCode")
|
||||||
|
soup = BeautifulSoup(response.content, 'html.parser')
|
||||||
|
soup = soup.find('form', {'id': 'qrCodeForm'})
|
||||||
|
return soup.find('a')['href']
|
||||||
|
|
||||||
|
def get_generate_username(self, max_username_index: int):
|
||||||
|
max_username_index += 1
|
||||||
|
if max_username_index % 10 == 4:
|
||||||
|
max_username_index += 1
|
||||||
|
return max_username_index
|
||||||
|
|
||||||
|
def set_security_pin(self, security_pin: str):
|
||||||
|
token = self.get_security_pin_form_token()
|
||||||
|
security_data = self.get_security_pin_data(token, security_pin)
|
||||||
|
response = self.session.post(
|
||||||
|
f'{self.base_url}/cm/saveSecurityPin',
|
||||||
|
data=security_data,
|
||||||
|
headers=self.set_security_pin_headers
|
||||||
|
)
|
||||||
|
|
||||||
|
def transfer_credit(self, t_username: str, t_password: str, amount: float):
|
||||||
|
token = self.get_transfer_token()
|
||||||
|
transfer_search_data = self.get_transfer_search_data(token, t_username)
|
||||||
|
response = self.session.post(
|
||||||
|
f'{self.base_url}/cm/searchTransferUser',
|
||||||
|
data=transfer_search_data,
|
||||||
|
headers=self.transfer_search_headers
|
||||||
|
)
|
||||||
|
soup = BeautifulSoup(response.content, 'html.parser')
|
||||||
|
name = soup.find('input', {'id': "name"})['value']
|
||||||
|
token = soup.find('input', {'name': "token"})['value']
|
||||||
|
toUserId = soup.find('input', {'id': "toUserId"})['value']
|
||||||
|
transfer_data = self.get_transfer_data(token, t_username, name, toUserId, amount, t_password)
|
||||||
|
response = self.session.post(
|
||||||
|
f'{self.base_url}/cm/saveTransfer',
|
||||||
|
data=transfer_data,
|
||||||
|
headers=self.transfer_credit_headers
|
||||||
|
)
|
||||||
|
# with open('transfer_credit.html', 'wb') as f:
|
||||||
|
# f.write(response.content)
|
||||||
|
return True if re.search(r'Successfully saved the record\.', response.text) else False
|
||||||
|
|
||||||
|
def get_user_credit(self):
|
||||||
|
response = self.session.post(
|
||||||
|
f'{self.base_url}/cm/userProfile',
|
||||||
|
headers=self.get_user_credit_headers
|
||||||
|
)
|
||||||
|
soup = BeautifulSoup(response.content, 'html.parser')
|
||||||
|
return float(soup.find('table', {'class': 'generalContent'}).find(text=re.compile('Credit Available')).parent.parent.find_all('td')[2].text)
|
||||||
|
|
||||||
|
def get_transfer_token(self):
|
||||||
|
response = self.session.get(f'{self.base_url}/cm/transfer')
|
||||||
|
soup = BeautifulSoup(response.content, 'html.parser')
|
||||||
|
return soup.find('input', {'name' : "token"})['value']
|
||||||
|
|
||||||
|
def logout(self):
|
||||||
|
"""Logout from the system."""
|
||||||
|
self.session.close()
|
||||||
|
self.is_logged_in = False
|
||||||
|
print("Logged out successfully.")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# user_id='testing0001'
|
||||||
|
# user_pass='Qwer1@34'
|
||||||
|
|
||||||
|
# # prefix = '13c'
|
||||||
|
user_manager = CM_BOT()
|
||||||
|
|
||||||
|
user_manager.login(
|
||||||
|
username = '13c4021',
|
||||||
|
password = 'vX34wUk'
|
||||||
|
)
|
||||||
|
|
||||||
|
user_manager.transfer_credit('m94', 'Sky533535', 0.01)
|
||||||
|
|
||||||
|
# last_username = user_manager.get_max_user_in_pattern(prefix)
|
||||||
|
# user_id = f'{prefix}{user_manager.get_generate_username(last_username)}'
|
||||||
|
# user_pass = user_manager.get_random_password()
|
||||||
|
|
||||||
|
# print(user_id)
|
||||||
|
# print(user_pass)
|
||||||
|
|
||||||
|
# user_manager.register_user(
|
||||||
|
# user_id=user_id,
|
||||||
|
# user_password=user_pass
|
||||||
|
# )
|
||||||
|
|
||||||
|
# user_manager.logout()
|
||||||
|
|
||||||
|
# user_manager = CM_BOT(
|
||||||
|
# username = user_id,
|
||||||
|
# password = user_pass
|
||||||
|
# )
|
||||||
|
# user_manager.login(user_id, user_pass)
|
||||||
|
# print(user_manager.get_register_link())
|
||||||
|
|
||||||
|
# user_manager.login(
|
||||||
|
# username = user_id,
|
||||||
|
# password = user_pass
|
||||||
|
# )
|
||||||
|
|
||||||
|
# user_manager.set_security_pin(user_pass)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
187
cm_bot_hal.py
Normal file
187
cm_bot_hal.py
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
import requests, re
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
from cm_bot import CM_BOT
|
||||||
|
from db import DB
|
||||||
|
|
||||||
|
import secrets, string
|
||||||
|
|
||||||
|
class CM_BOT_HAL:
|
||||||
|
def __init__(self):
|
||||||
|
self.db = DB()
|
||||||
|
self.prefix = '13c'
|
||||||
|
self.agent_id = 'cm13a3'
|
||||||
|
self.agent_password = 'Sky533535'
|
||||||
|
self.security_pin = 'Sky533535'
|
||||||
|
|
||||||
|
def get_random_password(self):
|
||||||
|
length = 8
|
||||||
|
lower_case = string.ascii_lowercase
|
||||||
|
upper_case = string.ascii_uppercase
|
||||||
|
digits = string.digits
|
||||||
|
all_characters = lower_case + upper_case + digits
|
||||||
|
|
||||||
|
password_list = [
|
||||||
|
secrets.choice(lower_case),
|
||||||
|
secrets.choice(upper_case),
|
||||||
|
secrets.choice(digits),
|
||||||
|
secrets.choice(digits),
|
||||||
|
secrets.choice(digits)
|
||||||
|
]
|
||||||
|
|
||||||
|
while len(password_list) < length:
|
||||||
|
password_list.append(secrets.choice(all_characters))
|
||||||
|
|
||||||
|
secrets.SystemRandom().shuffle(password_list)
|
||||||
|
|
||||||
|
return "".join(password_list)
|
||||||
|
|
||||||
|
def get_user_data_from_acc(self):
|
||||||
|
query = "SELECT username, password, link FROM acc WHERE status = %s ORDER BY username ASC LIMIT 1"
|
||||||
|
query_params = ['']
|
||||||
|
result = self.db.query(query, query_params)
|
||||||
|
return result[0] if len(result) else None
|
||||||
|
|
||||||
|
def get_max_username(self, prefix: str):
|
||||||
|
query = "SELECT username FROM acc WHERE username LIKE %s ORDER BY username DESC LIMIT 1"
|
||||||
|
query_params = [f'{prefix}%']
|
||||||
|
result = self.db.query(query, query_params)
|
||||||
|
return result[0]['username']
|
||||||
|
|
||||||
|
def get_next_username(self, prefix: str):
|
||||||
|
last_index = int(self.get_max_username(prefix).replace(prefix, ''))
|
||||||
|
next_index = last_index + 2 if last_index % 10 == 3 else last_index + 1
|
||||||
|
return f'{prefix}{next_index}'
|
||||||
|
|
||||||
|
def insert_user_to_table_acc(self, user):
|
||||||
|
query = "INSERT INTO acc (username, password, link) VALUES (%s, %s, %s)"
|
||||||
|
query_params = [user['username'], user['password'], user['link']]
|
||||||
|
return self.db.execute(query, query_params)
|
||||||
|
|
||||||
|
def insert_user_to_table_user(self, user):
|
||||||
|
query = "INSERT INTO user (f_username, f_password, t_username, t_password) VALUES (%s, %s, %s, %s)"
|
||||||
|
query_params = [user['f_username'], user['f_password'], user['t_username'], user['t_password']]
|
||||||
|
return self.db.execute(query, query_params)
|
||||||
|
|
||||||
|
def create_new_acc(self):
|
||||||
|
cm_bot = CM_BOT()
|
||||||
|
username = self.get_next_username(self.prefix)
|
||||||
|
password = self.get_random_password()
|
||||||
|
cm_bot.login(
|
||||||
|
username = self.agent_id,
|
||||||
|
password = self.agent_password
|
||||||
|
)
|
||||||
|
cm_bot.register_user(
|
||||||
|
user_id = username,
|
||||||
|
user_password = password
|
||||||
|
)
|
||||||
|
cm_bot.logout()
|
||||||
|
|
||||||
|
cm_bot = CM_BOT()
|
||||||
|
cm_bot.login(
|
||||||
|
username = username,
|
||||||
|
password = password
|
||||||
|
)
|
||||||
|
link = cm_bot.get_register_link()
|
||||||
|
cm_bot.logout()
|
||||||
|
|
||||||
|
user = {'username': username, 'password': password, 'link': link}
|
||||||
|
self.insert_user_to_table_acc(user)
|
||||||
|
return user
|
||||||
|
|
||||||
|
def update_user_status_to_wait(self, username: str):
|
||||||
|
query = "UPDATE acc SET status = 'wait' WHERE username = %s"
|
||||||
|
query_params = [username]
|
||||||
|
return self.db.execute(query, query_params)
|
||||||
|
|
||||||
|
def update_user_status_to_done(self, username: str):
|
||||||
|
query = "UPDATE acc SET status = 'done' WHERE username = %s"
|
||||||
|
query_params = [username]
|
||||||
|
return self.db.execute(query, query_params)
|
||||||
|
|
||||||
|
def get_user_api(self):
|
||||||
|
user = self.get_user_data_from_acc()
|
||||||
|
if user is None:
|
||||||
|
user = self.create_new_acc()
|
||||||
|
self.update_user_status_to_wait(user['username'])
|
||||||
|
return user
|
||||||
|
|
||||||
|
def is_whatsapp_url(self, text):
|
||||||
|
url_pattern = re.compile(
|
||||||
|
r'^(https?://)?' # Optional http:// or https://
|
||||||
|
r'((www\.)|([a-zA-Z0-9-]+\.))+' # www. or subdomain.
|
||||||
|
# r'[a-zA-Z]{2,6}' # Top-level domain (e.g., com, org, net)
|
||||||
|
r'(whatsapp.com)'
|
||||||
|
r'(/[a-zA-Z0-9-._~:/?#\[\]@!$&\'()*+,;=]*)?$' # Optional path, query, fragment
|
||||||
|
)
|
||||||
|
return bool(url_pattern.search(text))
|
||||||
|
|
||||||
|
def get_whatsapp_link_username(self, whatsapp_link: str):
|
||||||
|
if self.is_whatsapp_url(whatsapp_link) == False:
|
||||||
|
return None
|
||||||
|
response = requests.get(whatsapp_link)
|
||||||
|
soup = BeautifulSoup(response.content, 'html.parser')
|
||||||
|
username = [x.replace('*', '').replace(' ', '') for x in soup.find('h3', {"class": "_9vd5 _9scr"}).text.split("/")]
|
||||||
|
return username
|
||||||
|
|
||||||
|
def get_user_pass_from_acc(self, username: str):
|
||||||
|
query = "SELECT password FROM acc WHERE username = %s"
|
||||||
|
query_params = [username]
|
||||||
|
result = self.db.query(query, query_params)
|
||||||
|
return result[0]['password']
|
||||||
|
|
||||||
|
def set_security_pin_api(self, whatsapp_link: str):
|
||||||
|
t_username, f_username = self.get_whatsapp_link_username(whatsapp_link)
|
||||||
|
password = self.get_user_pass_from_acc(f_username)
|
||||||
|
cm_bot = CM_BOT()
|
||||||
|
cm_bot.login(
|
||||||
|
username = f_username,
|
||||||
|
password = password
|
||||||
|
)
|
||||||
|
cm_bot.set_security_pin(self.security_pin)
|
||||||
|
cm_bot.logout()
|
||||||
|
|
||||||
|
result = self.update_user_status_to_done(f_username)
|
||||||
|
if result == False:
|
||||||
|
raise Exception('Failed to update user status to done')
|
||||||
|
|
||||||
|
result = self.insert_user_to_table_user(
|
||||||
|
{
|
||||||
|
'f_username': f_username,
|
||||||
|
'f_password': password,
|
||||||
|
't_username': t_username,
|
||||||
|
't_password': self.security_pin
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if result == False:
|
||||||
|
raise Exception('Failed to insert user to table user')
|
||||||
|
|
||||||
|
def get_user_credit(self, f_username: str, f_password: str):
|
||||||
|
cm_bot = CM_BOT()
|
||||||
|
cm_bot.login(
|
||||||
|
username = f_username,
|
||||||
|
password = f_password
|
||||||
|
)
|
||||||
|
return float(cm_bot.get_user_credit())
|
||||||
|
|
||||||
|
def transfer_credit_api(self, f_username: str, f_password: str, t_username: str, t_password: str):
|
||||||
|
cm_bot = CM_BOT()
|
||||||
|
cm_bot.login(
|
||||||
|
username = f_username,
|
||||||
|
password = f_password
|
||||||
|
)
|
||||||
|
amount = cm_bot.get_user_credit() - 0.01
|
||||||
|
if cm_bot.transfer_credit(t_username, t_password, amount) == True:
|
||||||
|
print(f'Successfully transfer amount: {amount} from {f_username} to {t_username}')
|
||||||
|
else:
|
||||||
|
print(f'Failed to transfer credit from {f_username} to {t_username}')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
bot = CM_BOT_HAL()
|
||||||
|
# bot.transfer_credit_api('13c4070', 'zU2QoL', '4753kit', 'Sky533535')
|
||||||
|
# print(bot.get_next_username('13c'))
|
||||||
|
# print(bot.get_random_password())
|
||||||
|
# bot.get_user_api()
|
||||||
|
# bot.insert_user_to_table_acc({'username': 'test0001', 'password': 'test0001', 'link': 'test0001'})
|
||||||
|
# print(bot.get_whatsapp_link_username('https://chat.whatsapp.com/DZDWcicr6MTFrR4kBfnJXO'))
|
||||||
|
# print(bot.get_user_pass_from_acc('13c4151'))
|
||||||
85
cm_telegram.py
Normal file
85
cm_telegram.py
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import logging
|
||||||
|
|
||||||
|
from telegram import ForceReply, Update
|
||||||
|
from telegram.ext import Application, CommandHandler, ContextTypes, MessageHandler, filters
|
||||||
|
|
||||||
|
from cm_bot_hal import CM_BOT_HAL
|
||||||
|
|
||||||
|
logging.basicConfig(
|
||||||
|
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO
|
||||||
|
)
|
||||||
|
logging.getLogger("httpx").setLevel(logging.WARNING)
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
async def menu_cmd_handler(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||||
|
menu = [
|
||||||
|
'MENU',
|
||||||
|
'/1 - Get Acc',
|
||||||
|
'/2 <link> - Set Security Pin'
|
||||||
|
]
|
||||||
|
await update.message.reply_text('\n'.join(menu))
|
||||||
|
|
||||||
|
async def get_acc_handler(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||||
|
await update.message.reply_text('Start Getting CM Account ...')
|
||||||
|
try:
|
||||||
|
bot = CM_BOT_HAL()
|
||||||
|
user = bot.get_user_api()
|
||||||
|
msg = [
|
||||||
|
f'Username: {user["username"]}',
|
||||||
|
f'Password: {user["password"]}',
|
||||||
|
f'Link: {user["link"]}'
|
||||||
|
]
|
||||||
|
await update.message.reply_text('\n'.join(msg))
|
||||||
|
except Exception as e:
|
||||||
|
await update.message.reply_text(f'Error: {e}')
|
||||||
|
|
||||||
|
async def set_security_handler(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||||
|
if len(context.args) == 0 or len(context.args) > 1:
|
||||||
|
await update.message.reply_text('CMD is wrong, please check and retry ...')
|
||||||
|
return
|
||||||
|
bot = CM_BOT_HAL()
|
||||||
|
if bot.is_whatsapp_url(context.args[0]) == False:
|
||||||
|
await update.message.reply_text('Link Format Wrong, please check and retry ...')
|
||||||
|
return
|
||||||
|
await update.message.reply_text('Start Setting Security Pin ...')
|
||||||
|
try:
|
||||||
|
bot.set_security_pin_api(context.args[0])
|
||||||
|
del bot
|
||||||
|
await update.message.reply_text('Security Pin Set Done!')
|
||||||
|
except Exception as e:
|
||||||
|
await update.message.reply_text(f'Error: {e}')
|
||||||
|
|
||||||
|
async def insert_to_user_table_handler(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||||
|
if len(context.args) == 0 or len(context.args) != 4:
|
||||||
|
await update.message.reply_text('CMD is wrong, please check and retry ...')
|
||||||
|
return
|
||||||
|
bot = CM_BOT_HAL()
|
||||||
|
f_username, f_password, t_username, t_password = context.args
|
||||||
|
bot.insert_user_to_table_user(
|
||||||
|
{
|
||||||
|
'f_username': f_username,
|
||||||
|
'f_password': f_password,
|
||||||
|
't_username': t_username,
|
||||||
|
't_password': t_password
|
||||||
|
}
|
||||||
|
)
|
||||||
|
await update.message.reply_text(f'Done insert {f_username} into user table.')
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
"""Start the bot."""
|
||||||
|
# application = Application.builder().token("5327571437:AAFlowwnAysTEMx6LtYQNTevGCboKDZoYzY").build()
|
||||||
|
application = Application.builder().token("5315819168:AAH31xwNgPdnk123x97XalmTW6fQV5EUCFU").build()
|
||||||
|
application.add_handler(CommandHandler("menu", menu_cmd_handler))
|
||||||
|
application.add_handler(CommandHandler("1", get_acc_handler))
|
||||||
|
application.add_handler(CommandHandler("2", set_security_handler))
|
||||||
|
application.add_handler(CommandHandler("3", insert_to_user_table_handler))
|
||||||
|
# application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, echo))
|
||||||
|
|
||||||
|
# Start the Telegram bot
|
||||||
|
print("Starting Telegram bot...")
|
||||||
|
application.run_polling(allowed_updates=Update.ALL_TYPES)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
37
cm_transfer_credit.py
Normal file
37
cm_transfer_credit.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
from cm_bot_hal import CM_BOT_HAL
|
||||||
|
import logging, time, requests, json
|
||||||
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
|
from datetime import datetime
|
||||||
|
from tqdm import tqdm
|
||||||
|
|
||||||
|
logging.basicConfig(
|
||||||
|
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO
|
||||||
|
)
|
||||||
|
logging.getLogger("httpx").setLevel(logging.WARNING)
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
api_url = 'https://api.luckytown888.net'
|
||||||
|
max_threading = 1
|
||||||
|
|
||||||
|
def transfer(data: dict):
|
||||||
|
bot = CM_BOT_HAL()
|
||||||
|
logger.info(f'[Start] Transfer Credit from {data['f_username']} to {data['t_username']}')
|
||||||
|
bot.transfer_credit_api(data['f_username'], data['f_password'], data['t_username'], data['t_password'])
|
||||||
|
logger.info(f'[DONE] {data['f_username']} transfer done!')
|
||||||
|
del bot
|
||||||
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
weekday = int(datetime.now().strftime("%w"))
|
||||||
|
hour = int(datetime.now().strftime("%H"))
|
||||||
|
minutes = int(datetime.now().strftime("%M"))
|
||||||
|
if weekday == 3 and (hour >= 21 and hour < 22) and minutes >= 32:
|
||||||
|
response = requests.get(f'{api_url}/user')
|
||||||
|
items = json.loads(response.text)
|
||||||
|
total_items = len(items) if isinstance(items, list) else 0
|
||||||
|
if total_items == 0:
|
||||||
|
logger.info("No items to process.")
|
||||||
|
else:
|
||||||
|
with ThreadPoolExecutor(max_workers=max_threading) as executor:
|
||||||
|
list(tqdm(executor.map(transfer, items), total=total_items, desc="Processing data"))
|
||||||
|
time.sleep(1)
|
||||||
745
cm_web_view.py
Normal file
745
cm_web_view.py
Normal file
@ -0,0 +1,745 @@
|
|||||||
|
from flask import Flask, render_template_string, request, jsonify
|
||||||
|
from flask_cors import CORS
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
CORS(app)
|
||||||
|
|
||||||
|
# API base URL - use environment variable for Docker Compose
|
||||||
|
import os
|
||||||
|
API_BASE_URL = os.getenv('API_BASE_URL', 'http://localhost:3000')
|
||||||
|
print("API: ", API_BASE_URL)
|
||||||
|
|
||||||
|
# Beautiful HTML template with modern styling
|
||||||
|
HTML_TEMPLATE = """
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>CM Bot Database Viewer</title>
|
||||||
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
min-height: 100vh;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header h1 {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header p {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabs {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab {
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
border: none;
|
||||||
|
color: white;
|
||||||
|
padding: 15px 30px;
|
||||||
|
margin: 0 10px;
|
||||||
|
border-radius: 25px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.2);
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab.active {
|
||||||
|
background: rgba(255, 255, 255, 0.3);
|
||||||
|
box-shadow: 0 4px 15px rgba(0,0,0,0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
background: rgba(255, 255, 255, 0.95);
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 30px;
|
||||||
|
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
overflow-x: auto;
|
||||||
|
border-radius: 15px;
|
||||||
|
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
background: white;
|
||||||
|
border-radius: 15px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
color: white;
|
||||||
|
padding: 20px;
|
||||||
|
text-align: left;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 1rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
padding: 18px 20px;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:hover {
|
||||||
|
background: linear-gradient(135deg, #f8f9ff 0%, #f0f2ff 100%);
|
||||||
|
transform: scale(1.01);
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:last-child td {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-badge {
|
||||||
|
padding: 6px 12px;
|
||||||
|
border-radius: 20px;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
font-weight: 600;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-active {
|
||||||
|
background: #d4edda;
|
||||||
|
color: #155724;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-inactive {
|
||||||
|
background: #f8d7da;
|
||||||
|
color: #721c24;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editable {
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editable:hover {
|
||||||
|
background: #e3f2fd !important;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editable.editing {
|
||||||
|
background: #fff3e0 !important;
|
||||||
|
border: 2px solid #ff9800;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit-input {
|
||||||
|
width: 100%;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
padding: 4px 8px;
|
||||||
|
font-size: inherit;
|
||||||
|
font-family: inherit;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit-buttons {
|
||||||
|
display: inline-flex;
|
||||||
|
gap: 5px;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit-btn {
|
||||||
|
padding: 4px 8px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
font-weight: 600;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.save-btn {
|
||||||
|
background: #4caf50;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.save-btn:hover {
|
||||||
|
background: #45a049;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cancel-btn {
|
||||||
|
background: #f44336;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cancel-btn:hover {
|
||||||
|
background: #da190b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit-icon {
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.2s ease;
|
||||||
|
margin-left: 5px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editable:hover .edit-icon {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sort-indicator {
|
||||||
|
margin-left: 5px;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sortable {
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sortable:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading {
|
||||||
|
text-align: center;
|
||||||
|
padding: 50px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading i {
|
||||||
|
font-size: 2rem;
|
||||||
|
animation: spin 1s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
0% { transform: rotate(0deg); }
|
||||||
|
100% { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
background: #f8d7da;
|
||||||
|
color: #721c24;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
text-align: center;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.refresh-btn {
|
||||||
|
background: linear-gradient(135deg, #28a745 0%, #20c997 100%);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 12px 25px;
|
||||||
|
border-radius: 25px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.refresh-btn:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||||
|
gap: 20px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card {
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
color: white;
|
||||||
|
padding: 25px;
|
||||||
|
border-radius: 15px;
|
||||||
|
text-align: center;
|
||||||
|
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card h3 {
|
||||||
|
font-size: 2rem;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card p {
|
||||||
|
opacity: 0.9;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.header h1 {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabs {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab {
|
||||||
|
margin: 5px 0;
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="header">
|
||||||
|
<h1><i class="fas fa-database"></i> CM Bot Database Viewer</h1>
|
||||||
|
<p>Real-time view of accounts and users data</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tabs">
|
||||||
|
<button class="tab active" onclick="showTab('acc')">
|
||||||
|
<i class="fas fa-user-circle"></i> Accounts
|
||||||
|
</button>
|
||||||
|
<button class="tab" onclick="showTab('user')">
|
||||||
|
<i class="fas fa-users"></i> Users
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<button class="refresh-btn" onclick="refreshData()">
|
||||||
|
<i class="fas fa-sync-alt"></i> Refresh Data
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div id="stats" class="stats" style="display: none;">
|
||||||
|
<div class="stat-card">
|
||||||
|
<h3 id="acc-count">0</h3>
|
||||||
|
<p>Total Accounts</p>
|
||||||
|
</div>
|
||||||
|
<div class="stat-card">
|
||||||
|
<h3 id="user-count">0</h3>
|
||||||
|
<p>Total Users</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="acc-content" class="tab-content">
|
||||||
|
<div class="loading">
|
||||||
|
<i class="fas fa-spinner"></i>
|
||||||
|
<p>Loading accounts...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="user-content" class="tab-content" style="display: none;">
|
||||||
|
<div class="loading">
|
||||||
|
<i class="fas fa-spinner"></i>
|
||||||
|
<p>Loading users...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
let currentTab = 'acc';
|
||||||
|
let accData = [];
|
||||||
|
let userData = [];
|
||||||
|
let editingCell = null;
|
||||||
|
let originalValue = null;
|
||||||
|
|
||||||
|
function showTab(tab) {
|
||||||
|
// Update tab buttons
|
||||||
|
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
|
||||||
|
event.target.classList.add('active');
|
||||||
|
|
||||||
|
// Show/hide content
|
||||||
|
document.getElementById('acc-content').style.display = tab === 'acc' ? 'block' : 'none';
|
||||||
|
document.getElementById('user-content').style.display = tab === 'user' ? 'block' : 'none';
|
||||||
|
|
||||||
|
currentTab = tab;
|
||||||
|
|
||||||
|
// Load data if not already loaded
|
||||||
|
if (tab === 'acc' && accData.length === 0) {
|
||||||
|
loadAccData();
|
||||||
|
} else if (tab === 'user' && userData.length === 0) {
|
||||||
|
loadUserData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadAccData() {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/acc/');
|
||||||
|
if (!response.ok) throw new Error('Failed to fetch accounts');
|
||||||
|
|
||||||
|
accData = await response.json();
|
||||||
|
displayAccData();
|
||||||
|
updateStats();
|
||||||
|
} catch (error) {
|
||||||
|
document.getElementById('acc-content').innerHTML =
|
||||||
|
`<div class="error">Error loading accounts: ${error.message}</div>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadUserData() {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/user/');
|
||||||
|
if (!response.ok) throw new Error('Failed to fetch users');
|
||||||
|
|
||||||
|
userData = await response.json();
|
||||||
|
displayUserData();
|
||||||
|
updateStats();
|
||||||
|
} catch (error) {
|
||||||
|
document.getElementById('user-content').innerHTML =
|
||||||
|
`<div class="error">Error loading users: ${error.message}</div>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function displayAccData() {
|
||||||
|
const container = document.getElementById('acc-content');
|
||||||
|
|
||||||
|
if (accData.length === 0) {
|
||||||
|
container.innerHTML = '<div class="error">No accounts found</div>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort data with 13c prefix priority
|
||||||
|
const sortedData = sortData([...accData], 'acc');
|
||||||
|
|
||||||
|
const table = `
|
||||||
|
<div class="table-container">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="sortable"><i class="fas fa-user"></i> Username</th>
|
||||||
|
<th><i class="fas fa-lock"></i> Password <i class="fas fa-edit edit-icon"></i></th>
|
||||||
|
<th><i class="fas fa-info-circle"></i> Status <i class="fas fa-edit edit-icon"></i></th>
|
||||||
|
<th><i class="fas fa-link"></i> Link <i class="fas fa-edit edit-icon"></i></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
${sortedData.map((acc, index) => `
|
||||||
|
<tr>
|
||||||
|
<td><strong>${acc.username || 'N/A'}</strong></td>
|
||||||
|
<td class="editable" onclick="startEdit(this, 'password', 'acc', ${accData.findIndex(a => a.username === acc.username)})">
|
||||||
|
${acc.password || 'N/A'}
|
||||||
|
</td>
|
||||||
|
<td class="editable" onclick="startEdit(this, 'status', 'acc', ${accData.findIndex(a => a.username === acc.username)})">
|
||||||
|
<span class="status-badge ${acc.status === 'active' ? 'status-active' : 'status-inactive'}">
|
||||||
|
${acc.status || 'N/A'}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td class="editable" onclick="startEdit(this, 'link', 'acc', ${accData.findIndex(a => a.username === acc.username)})">
|
||||||
|
${acc.link || 'N/A'}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
`).join('')}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
container.innerHTML = table;
|
||||||
|
}
|
||||||
|
|
||||||
|
function displayUserData() {
|
||||||
|
const container = document.getElementById('user-content');
|
||||||
|
|
||||||
|
if (userData.length === 0) {
|
||||||
|
container.innerHTML = '<div class="error">No users found</div>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort data with 13c prefix priority and by update time
|
||||||
|
const sortedData = sortData([...userData], 'user');
|
||||||
|
|
||||||
|
const table = `
|
||||||
|
<div class="table-container">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="sortable"><i class="fas fa-user"></i> From Username</th>
|
||||||
|
<th><i class="fas fa-lock"></i> From Password <i class="fas fa-edit edit-icon"></i></th>
|
||||||
|
<th><i class="fas fa-user"></i> To Username <i class="fas fa-edit edit-icon"></i></th>
|
||||||
|
<th><i class="fas fa-lock"></i> To Password <i class="fas fa-edit edit-icon"></i></th>
|
||||||
|
<th class="sortable"><i class="fas fa-clock"></i> Last Update</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
${sortedData.map((user, index) => `
|
||||||
|
<tr>
|
||||||
|
<td><strong>${user.f_username || 'N/A'}</strong></td>
|
||||||
|
<td class="editable" onclick="startEdit(this, 'f_password', 'user', ${userData.findIndex(u => u.f_username === user.f_username)})">
|
||||||
|
${user.f_password || 'N/A'}
|
||||||
|
</td>
|
||||||
|
<td class="editable" onclick="startEdit(this, 't_username', 'user', ${userData.findIndex(u => u.f_username === user.f_username)})">
|
||||||
|
<strong>${user.t_username || 'N/A'}</strong>
|
||||||
|
</td>
|
||||||
|
<td class="editable" onclick="startEdit(this, 't_password', 'user', ${userData.findIndex(u => u.f_username === user.f_username)})">
|
||||||
|
${user.t_password || 'N/A'}
|
||||||
|
</td>
|
||||||
|
<td>${user.last_update_time || 'N/A'}</td>
|
||||||
|
</tr>
|
||||||
|
`).join('')}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
container.innerHTML = table;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateStats() {
|
||||||
|
document.getElementById('acc-count').textContent = accData.length;
|
||||||
|
document.getElementById('user-count').textContent = userData.length;
|
||||||
|
document.getElementById('stats').style.display = 'grid';
|
||||||
|
}
|
||||||
|
|
||||||
|
function refreshData() {
|
||||||
|
if (currentTab === 'acc') {
|
||||||
|
loadAccData();
|
||||||
|
} else {
|
||||||
|
loadUserData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sorting functions
|
||||||
|
function sortData(data, type) {
|
||||||
|
if (type === 'acc') {
|
||||||
|
return data.sort((a, b) => {
|
||||||
|
// 13c prefix always on top
|
||||||
|
const aIs13c = a.username && a.username.startsWith('13c');
|
||||||
|
const bIs13c = b.username && b.username.startsWith('13c');
|
||||||
|
|
||||||
|
if (aIs13c && !bIs13c) return -1;
|
||||||
|
if (!aIs13c && bIs13c) return 1;
|
||||||
|
|
||||||
|
// If both are 13c or both are not 13c, sort by username in descending order
|
||||||
|
if (aIs13c && bIs13c) {
|
||||||
|
return (b.username || '').localeCompare(a.username || '');
|
||||||
|
} else {
|
||||||
|
return (b.username || '').localeCompare(a.username || '');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (type === 'user') {
|
||||||
|
return data.sort((a, b) => {
|
||||||
|
// 13c prefix always on top
|
||||||
|
const aIs13c = a.f_username && a.f_username.startsWith('13c');
|
||||||
|
const bIs13c = b.f_username && b.f_username.startsWith('13c');
|
||||||
|
|
||||||
|
if (aIs13c && !bIs13c) return -1;
|
||||||
|
if (!aIs13c && bIs13c) return 1;
|
||||||
|
|
||||||
|
// Then sort by last_update_time (newest first)
|
||||||
|
const aTime = new Date(a.last_update_time || 0);
|
||||||
|
const bTime = new Date(b.last_update_time || 0);
|
||||||
|
return bTime - aTime;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Editing functions
|
||||||
|
function startEdit(cell, field, type, index) {
|
||||||
|
if (editingCell) {
|
||||||
|
cancelEdit();
|
||||||
|
}
|
||||||
|
|
||||||
|
editingCell = cell;
|
||||||
|
originalValue = cell.textContent.trim();
|
||||||
|
|
||||||
|
const input = document.createElement('input');
|
||||||
|
input.type = 'text';
|
||||||
|
input.className = 'edit-input';
|
||||||
|
input.value = originalValue;
|
||||||
|
|
||||||
|
const buttons = document.createElement('div');
|
||||||
|
buttons.className = 'edit-buttons';
|
||||||
|
buttons.innerHTML = `
|
||||||
|
<button class="edit-btn save-btn" onclick="saveEdit('${field}', '${type}', ${index})">
|
||||||
|
<i class="fas fa-check"></i>
|
||||||
|
</button>
|
||||||
|
<button class="edit-btn cancel-btn" onclick="cancelEdit()">
|
||||||
|
<i class="fas fa-times"></i>
|
||||||
|
</button>
|
||||||
|
`;
|
||||||
|
|
||||||
|
cell.innerHTML = '';
|
||||||
|
cell.appendChild(input);
|
||||||
|
cell.appendChild(buttons);
|
||||||
|
cell.classList.add('editing');
|
||||||
|
|
||||||
|
input.focus();
|
||||||
|
input.select();
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelEdit() {
|
||||||
|
if (editingCell) {
|
||||||
|
editingCell.textContent = originalValue;
|
||||||
|
editingCell.classList.remove('editing');
|
||||||
|
editingCell = null;
|
||||||
|
originalValue = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function saveEdit(field, type, index) {
|
||||||
|
if (!editingCell) return;
|
||||||
|
|
||||||
|
const input = editingCell.querySelector('.edit-input');
|
||||||
|
const newValue = input.value.trim();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (type === 'acc') {
|
||||||
|
const data = {
|
||||||
|
username: accData[index].username,
|
||||||
|
password: field === 'password' ? newValue : accData[index].password,
|
||||||
|
status: field === 'status' ? newValue : accData[index].status,
|
||||||
|
link: field === 'link' ? newValue : accData[index].link
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await fetch('/api/update-acc-data', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
accData[index][field] = newValue;
|
||||||
|
editingCell.textContent = newValue;
|
||||||
|
editingCell.classList.remove('editing');
|
||||||
|
editingCell = null;
|
||||||
|
originalValue = null;
|
||||||
|
} else {
|
||||||
|
throw new Error('Failed to update account data');
|
||||||
|
}
|
||||||
|
} else if (type === 'user') {
|
||||||
|
const data = {
|
||||||
|
f_username: userData[index].f_username,
|
||||||
|
f_password: field === 'f_password' ? newValue : userData[index].f_password,
|
||||||
|
t_username: field === 't_username' ? newValue : userData[index].t_username,
|
||||||
|
t_password: field === 't_password' ? newValue : userData[index].t_password
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await fetch('/api/update-user-data', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
userData[index][field] = newValue;
|
||||||
|
userData[index].last_update_time = new Date().toUTCString();
|
||||||
|
editingCell.textContent = newValue;
|
||||||
|
editingCell.classList.remove('editing');
|
||||||
|
editingCell = null;
|
||||||
|
originalValue = null;
|
||||||
|
} else {
|
||||||
|
throw new Error('Failed to update user data');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
alert('Error updating data: ' + error.message);
|
||||||
|
cancelEdit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load initial data
|
||||||
|
loadAccData();
|
||||||
|
|
||||||
|
// Auto-refresh every 30 seconds
|
||||||
|
setInterval(() => {
|
||||||
|
if (currentTab === 'acc') {
|
||||||
|
loadAccData();
|
||||||
|
} else {
|
||||||
|
loadUserData();
|
||||||
|
}
|
||||||
|
}, 30000);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
"""
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def index():
|
||||||
|
return render_template_string(HTML_TEMPLATE)
|
||||||
|
|
||||||
|
@app.route('/api/acc/')
|
||||||
|
def proxy_acc():
|
||||||
|
try:
|
||||||
|
response = requests.get(f"{API_BASE_URL}/acc/")
|
||||||
|
return jsonify(response.json())
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({"error": str(e)}), 500
|
||||||
|
|
||||||
|
@app.route('/api/user/')
|
||||||
|
def proxy_user():
|
||||||
|
try:
|
||||||
|
response = requests.get(f"{API_BASE_URL}/user/")
|
||||||
|
return jsonify(response.json())
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({"error": str(e)}), 500
|
||||||
|
|
||||||
|
@app.route('/api/update-acc-data', methods=['POST'])
|
||||||
|
def proxy_update_acc():
|
||||||
|
try:
|
||||||
|
data = request.get_json()
|
||||||
|
response = requests.post(f"{API_BASE_URL}/update-acc-data", json=data)
|
||||||
|
return jsonify(response.json()), response.status_code
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({"error": str(e)}), 500
|
||||||
|
|
||||||
|
@app.route('/api/update-user-data', methods=['POST'])
|
||||||
|
def proxy_update_user():
|
||||||
|
try:
|
||||||
|
data = request.get_json()
|
||||||
|
response = requests.post(f"{API_BASE_URL}/update-user-data", json=data)
|
||||||
|
return jsonify(response.json()), response.status_code
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({"error": str(e)}), 500
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
print("Starting CM Web View...")
|
||||||
|
print("Web interface will be available at: http://localhost:8000")
|
||||||
|
print("Make sure the API server is running on port 3000")
|
||||||
|
app.run(host='0.0.0.0', port=8000, debug=True)
|
||||||
99
db.py
Normal file
99
db.py
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
import mysql.connector
|
||||||
|
from mysql.connector import Error
|
||||||
|
|
||||||
|
class DB:
|
||||||
|
def __init__(self):
|
||||||
|
self.config = {
|
||||||
|
'host': '192.168.0.210',
|
||||||
|
'user': 'rex_cm',
|
||||||
|
'password': 'hengserver',
|
||||||
|
'database': 'rex_cm',
|
||||||
|
'port': 3306
|
||||||
|
}
|
||||||
|
self.init_database()
|
||||||
|
|
||||||
|
def get_connection(self):
|
||||||
|
"""Get MySQL database connection."""
|
||||||
|
try:
|
||||||
|
connection = mysql.connector.connect(**self.config)
|
||||||
|
return connection
|
||||||
|
except Error as e:
|
||||||
|
print(f"Error connecting to MySQL: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def init_database(self):
|
||||||
|
"""Initialize the database connection."""
|
||||||
|
connection = self.get_connection()
|
||||||
|
if connection is None:
|
||||||
|
raise Exception("Failed to connect to database")
|
||||||
|
|
||||||
|
try:
|
||||||
|
cursor = connection.cursor()
|
||||||
|
# Test connection by checking if required tables exist
|
||||||
|
cursor.execute("SHOW TABLES LIKE 'acc'")
|
||||||
|
if not cursor.fetchone():
|
||||||
|
raise Exception("Table 'acc' does not exist")
|
||||||
|
|
||||||
|
cursor.execute("SHOW TABLES LIKE 'user'")
|
||||||
|
if not cursor.fetchone():
|
||||||
|
raise Exception("Table 'user' does not exist")
|
||||||
|
|
||||||
|
print("Database connection verified - required tables exist")
|
||||||
|
|
||||||
|
except Error as e:
|
||||||
|
print(f"Error verifying database: {e}")
|
||||||
|
raise Exception(f"Database verification failed: {e}")
|
||||||
|
finally:
|
||||||
|
if connection.is_connected():
|
||||||
|
cursor.close()
|
||||||
|
connection.close()
|
||||||
|
|
||||||
|
def query(self, query, params=None):
|
||||||
|
"""Execute a query and return results."""
|
||||||
|
connection = self.get_connection()
|
||||||
|
if connection is None:
|
||||||
|
return []
|
||||||
|
|
||||||
|
try:
|
||||||
|
cursor = connection.cursor(dictionary=True)
|
||||||
|
|
||||||
|
if params:
|
||||||
|
cursor.execute(query, params)
|
||||||
|
else:
|
||||||
|
cursor.execute(query)
|
||||||
|
|
||||||
|
results = cursor.fetchall()
|
||||||
|
return results
|
||||||
|
|
||||||
|
except Error as e:
|
||||||
|
print(f"Error executing query: {e}")
|
||||||
|
return []
|
||||||
|
finally:
|
||||||
|
if connection.is_connected():
|
||||||
|
cursor.close()
|
||||||
|
connection.close()
|
||||||
|
|
||||||
|
def execute(self, query, params=None):
|
||||||
|
"""Execute a query that modifies data (INSERT, UPDATE, DELETE) and return success status."""
|
||||||
|
connection = self.get_connection()
|
||||||
|
if connection is None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
cursor = connection.cursor()
|
||||||
|
|
||||||
|
if params:
|
||||||
|
cursor.execute(query, params)
|
||||||
|
else:
|
||||||
|
cursor.execute(query)
|
||||||
|
|
||||||
|
connection.commit()
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Error as e:
|
||||||
|
print(f"Error executing query: {e}")
|
||||||
|
return False
|
||||||
|
finally:
|
||||||
|
if connection.is_connected():
|
||||||
|
cursor.close()
|
||||||
|
connection.close()
|
||||||
71
docker-compose.yml
Normal file
71
docker-compose.yml
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
services:
|
||||||
|
# Telegram Bot Service
|
||||||
|
telegram-bot:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.telegram
|
||||||
|
container_name: cm-telegram-bot
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
- PYTHONUNBUFFERED=1
|
||||||
|
volumes:
|
||||||
|
- .:/app
|
||||||
|
networks:
|
||||||
|
- cm-network
|
||||||
|
depends_on:
|
||||||
|
- api-server
|
||||||
|
|
||||||
|
# API Server Service
|
||||||
|
api-server:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.api
|
||||||
|
container_name: cm-api-server
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
environment:
|
||||||
|
- PYTHONUNBUFFERED=1
|
||||||
|
volumes:
|
||||||
|
- .:/app
|
||||||
|
networks:
|
||||||
|
- cm-network
|
||||||
|
|
||||||
|
# Web View Service
|
||||||
|
web-view:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.web
|
||||||
|
container_name: cm-web-view
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "8001:8000"
|
||||||
|
environment:
|
||||||
|
- PYTHONUNBUFFERED=1
|
||||||
|
- API_BASE_URL=http://api-server:3000
|
||||||
|
volumes:
|
||||||
|
- .:/app
|
||||||
|
networks:
|
||||||
|
- cm-network
|
||||||
|
depends_on:
|
||||||
|
- api-server
|
||||||
|
|
||||||
|
transfer-bot:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.transfer
|
||||||
|
container_name: cm-transfer-bot
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
- PYTHONUNBUFFERED=1
|
||||||
|
volumes:
|
||||||
|
- .:/app
|
||||||
|
networks:
|
||||||
|
- cm-network
|
||||||
|
depends_on:
|
||||||
|
- api-server
|
||||||
|
|
||||||
|
|
||||||
|
networks:
|
||||||
|
cm-network:
|
||||||
|
driver: bridge
|
||||||
7
requirements.txt
Normal file
7
requirements.txt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
Flask==2.3.3
|
||||||
|
mysql-connector-python==8.1.0
|
||||||
|
flask-cors==4.0.0
|
||||||
|
python-telegram-bot==22.4
|
||||||
|
requests==2.32.5
|
||||||
|
beautifulsoup4==4.13.5
|
||||||
|
tqdm==4.67.1
|
||||||
542
transfer_credit.html
Normal file
542
transfer_credit.html
Normal file
@ -0,0 +1,542 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- taglib uri="/struts-dojo-tags" prefix="sx" -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||||
|
<head>
|
||||||
|
<!-- HTTP 1.1 -->
|
||||||
|
<meta http-equiv="Cache-Control" content="no-store"/>
|
||||||
|
<!-- HTTP 1.0 -->
|
||||||
|
<meta http-equiv="Pragma" content="no-cache"/>
|
||||||
|
<!-- Prevents caching at the Proxy Server -->
|
||||||
|
<meta http-equiv="Expires" content="0"/>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||||
|
<meta http-equiv="Content-Style-Type" content="text/css" />
|
||||||
|
<meta name="generator" content="AppFuse 2.0" /> <!-- leave this for stats please -->
|
||||||
|
<link rel="icon" href="/cm/images/favicon.ico"/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script type="text/javascript" src="/cm/struts/js/base/jquery-1.7.2.min.js"></script>
|
||||||
|
<script type="text/javascript" src="/cm/struts/js/base/jquery.ui.core.min.js?s2j=3.3.3"></script>
|
||||||
|
<script type="text/javascript" src="/cm/struts/js/plugins/jquery.subscribe.min.js"></script>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="/cm/struts/js/struts2/jquery.struts2-3.3.3.min.js"></script>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function() {
|
||||||
|
jQuery.struts2_jquery.version="3.3.3";
|
||||||
|
jQuery.scriptPath = "/cm/struts/";
|
||||||
|
jQuery.struts2_jquery.gridLocal = "en";
|
||||||
|
jQuery.struts2_jquery.timeLocal = "en";
|
||||||
|
jQuery.ajaxSettings.traditional = true;
|
||||||
|
|
||||||
|
jQuery.ajaxSetup ({
|
||||||
|
cache: false
|
||||||
|
});
|
||||||
|
|
||||||
|
jQuery.struts2_jquery.require("js/struts2/jquery.ui.struts2-3.3.3.min.js");
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<link id="jquery_theme_link" rel="stylesheet" href="/cm/struts/themes/ui-lightness/jquery-ui.css?s2j=3.3.3" type="text/css"/>
|
||||||
|
|
||||||
|
|
||||||
|
<title>Transfer | </title>
|
||||||
|
|
||||||
|
<link rel="stylesheet" type="text/css" media="all" href="/cm/styles/cm/theme.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" media="print" href="/cm/styles/cm/print.css" />
|
||||||
|
|
||||||
|
<script type="text/javascript" src="/cm/scripts/global.js"></script>
|
||||||
|
<script type="text/javascript" src="/cm/scripts/clipboard.js"></script>
|
||||||
|
<script type="text/javascript" src="/cm/scripts/jquery.blockUI.js"></script>
|
||||||
|
<script type="text/javascript" src="/cm/scripts/date.format.js"></script>
|
||||||
|
|
||||||
|
<meta name="heading" content="Transfer"/>
|
||||||
|
<meta name="menu" content="CMDepositWithdrawal"/>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
function submitForm(){
|
||||||
|
document.getElementById("button_transfer").disabled = true;
|
||||||
|
document.transferForm.submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
function searchUser(){
|
||||||
|
document.transferForm.action = "searchTransferUser";
|
||||||
|
document.transferForm.submit();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script language="JavaScript">
|
||||||
|
function readCookie(name){
|
||||||
|
return(document.cookie.match('(^|; )'+name+'=([^;]*)')||0)[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
//document.onscroll= document.cookie='ypos=' + window.pageYOffset;
|
||||||
|
|
||||||
|
$(window).scroll(function () {
|
||||||
|
document.cookie = 'ypos=' + getYOffset();
|
||||||
|
});
|
||||||
|
|
||||||
|
function getYOffset() {
|
||||||
|
var pageY;
|
||||||
|
if(typeof(window.pageYOffset)=='number') {
|
||||||
|
pageY=window.pageYOffset;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pageY=document.documentElement.scrollTop;
|
||||||
|
}
|
||||||
|
return pageY;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body onload="window.scrollTo(0,readCookie('ypos'));">
|
||||||
|
|
||||||
|
<div id="page">
|
||||||
|
<div id="header" class="clearfix">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- taglib uri="/struts-dojo-tags" prefix="sx" -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div id="branding">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0">
|
||||||
|
<tr>
|
||||||
|
<td><span id="spanTime" class="text-hdr-time-11"></span></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div id="scrollingMsg">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" width="100%">
|
||||||
|
<tr>
|
||||||
|
<td><marquee behavior="scroll" direction="left" scrollamount="2" onmouseover="this.stop();" onmouseout="this.start();">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CM C/S Wsap: +601156938483
|
||||||
|
|
||||||
|
Special Draw 28.10.2025
|
||||||
|
|
||||||
|
Bayaran Baru(3600 - 5100)
|
||||||
|
|
||||||
|
CM Wsap: +601156938483 | FB:www.facebook.com/cmcashmarket
|
||||||
|
Web:www.cmcashmarket.net
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</marquee>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div id="branding2">
|
||||||
|
|
||||||
|
<strong><span class="text-hdr-time-11">Welcome!, 13c4021</span></strong>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a id="english" href="mainMenu?locale=en"><img height="10" width="16" src="/cm/images/hdr_lag_en.gif"></a> <a id="chinese" href="mainMenu?locale=zh"><img height="10" width="16" src="/cm/images/hdr_lag_cn.gif"></a>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div id="header-login">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="content" class="clearfix">
|
||||||
|
<div id="main">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- taglib uri="/struts-dojo-tags" prefix="sx" -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="message" id="successMessages">
|
||||||
|
|
||||||
|
<img src="/cm/images/iconInformation.gif" alt="Information" class="icon" />
|
||||||
|
Successfully saved the record.<br />
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- taglib uri="/struts-dojo-tags" prefix="sx" -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<form id="transferForm" method="post" action="saveTransfer" name="transferForm">
|
||||||
|
<input type="hidden" name="struts.token.name" value="token" />
|
||||||
|
<input type="hidden" name="token" value="GIO9ZJV4RUCFC48PHWDWLX7RX6TYZ6DQ" />
|
||||||
|
|
||||||
|
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||||
|
<tr>
|
||||||
|
<td height="40" bgcolor="#FFFFFF">
|
||||||
|
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||||
|
<tr>
|
||||||
|
<td width="20"> </td>
|
||||||
|
<td align="left" class="text-tt-18">Transfer</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td height="54" bgcolor="#f3f3f3" align="center">
|
||||||
|
<br>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<table id="depositTable" class="searchContent" border="0" style="width: 50%">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="bold" width="20%">Username : </td>
|
||||||
|
<td>
|
||||||
|
<input type="text" class="text medium" id="username" value="" name="username" >
|
||||||
|
|
||||||
|
<input id="search" class="button" type="button" onclick="javascript:searchUser();return false;" value="Search" name="button.search">
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(".numberOnly").bind("keyup paste", function(){
|
||||||
|
var val = $(this).val();
|
||||||
|
if(isNaN(val)){
|
||||||
|
val = val.replace(/[^0-9\.]/g, '');
|
||||||
|
if(val.split('.').length>2) val =val.replace(/\.+$/,"");
|
||||||
|
|
||||||
|
this.value = val;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
-->
|
||||||
|
<div id="nav">
|
||||||
|
<div class="wrapper">
|
||||||
|
<h2 class="accessibility">Navigation</h2>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- taglib uri="/struts-dojo-tags" prefix="sx" -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<table border="0" cellspacing="0" cellpadding="0" width="100%">
|
||||||
|
<tr>
|
||||||
|
<td class="bg-hdr-bar-blue" height="35px">
|
||||||
|
<div style="padding-left:30px; padding-right:30px">
|
||||||
|
<table width="100%" cellspacing="0" cellpadding="0" border="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td width="10%">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td width="90%" align="right">
|
||||||
|
<div id='cssmenu' class="menuList">
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/cm/mainMenu" title="Main Menu" class="text-mn-12">Main Menu</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li class="has-sub">
|
||||||
|
<a href="javascript:void(0)" title="Cash Wallet" class="current" class="text-mn-12">Cash Wallet</a>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/cm/transfer" title="Transfer" class="text-mn-12">Transfer</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="last">
|
||||||
|
<a href="/cm/history/transferTransactions" title="Transfer Transactions" class="text-mn-12">Transfer Transactions</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li class="has-sub">
|
||||||
|
<a href="javascript:void(0)" title="Reports" class="text-mn-12">Reports</a>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/cm/report/simpleWinLossDetail" title="Win Loss Report" class="text-mn-12">Win Loss Report</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/cm/report/betStatistic" title="Bet Statistic" class="text-mn-12">Bet Statistic</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/cm/report/drawResult" title="Draw Result" class="text-mn-12">Draw Result</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="last">
|
||||||
|
<a href="/cm/report/memberReport" title="Member Report" class="text-mn-12">Member Report</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li class="has-sub">
|
||||||
|
<a href="javascript:void(0)" title="Account" class="text-mn-12">Account</a>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/cm/showQrCode" title="QR Code" class="text-mn-12">QR Code</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/cm/register" title="Member Tree" class="text-mn-12">Member Tree</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/cm/changePassword" title="Change Password" class="text-mn-12">Change Password</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/cm/setSecurityPin" title="Change Security Pin" class="text-mn-12">Change Security Pin</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="last">
|
||||||
|
<a href="/cm/userPackageAction" title="Prize Package" class="text-mn-12">Prize Package</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/cm/logout" title="Logout" class="text-mn-12">Logout</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="bg-hdr-bar-shadow"> </td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<hr/>
|
||||||
|
</div><!-- end nav -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="footer" class="clearfix">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- taglib uri="/struts-dojo-tags" prefix="sx" -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<table width="100%" cellspacing="0" cellpadding="0" border="0">
|
||||||
|
<tr>
|
||||||
|
<td height="30" valign="top" bgcolor="#f6f6f6">
|
||||||
|
<table width="100%" cellspacing="0" cellpadding="0" border="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td height="25" width="30" valign="bottom"> </td>
|
||||||
|
<td valign="bottom" align="left" class="text-ftr-11">
|
||||||
|
Version 1.1.010
|
||||||
|
</td>
|
||||||
|
<td valign="bottom" align="right" class="text-ftr-11">
|
||||||
|
© 2017 <font color="#2881c1"><a href="https://cm99.net">cm99.net</a></font></td>
|
||||||
|
<td width="30" valign="bottom"> </td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
var timeServer = new Date(1759324187639);
|
||||||
|
//Users time
|
||||||
|
var timeLocal = new Date();
|
||||||
|
|
||||||
|
//Calculate the difference (returns milliseconds)
|
||||||
|
millDiff = timeLocal - timeServer;
|
||||||
|
|
||||||
|
//The ticking clock function
|
||||||
|
function TimeTick() {
|
||||||
|
//grab updated time
|
||||||
|
timeLocal = new Date();
|
||||||
|
//add time difference
|
||||||
|
timeLocal.setMilliseconds(timeLocal.getMilliseconds() - millDiff);
|
||||||
|
//display the value
|
||||||
|
// document.getElementById("spanTime").innerHTML = timeLocal.toLocaleFormat('%A, %d-%b-%Y %I:%M:%S%p');
|
||||||
|
document.getElementById("spanTime").innerHTML = timeLocal.format("dddd, dd-mmm-yyyy hh:MM:ssTT");
|
||||||
|
}
|
||||||
|
|
||||||
|
setInterval('TimeTick()', 500);
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
559
transfer_search.html
Normal file
559
transfer_search.html
Normal file
@ -0,0 +1,559 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- taglib uri="/struts-dojo-tags" prefix="sx" -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||||
|
<head>
|
||||||
|
<!-- HTTP 1.1 -->
|
||||||
|
<meta http-equiv="Cache-Control" content="no-store"/>
|
||||||
|
<!-- HTTP 1.0 -->
|
||||||
|
<meta http-equiv="Pragma" content="no-cache"/>
|
||||||
|
<!-- Prevents caching at the Proxy Server -->
|
||||||
|
<meta http-equiv="Expires" content="0"/>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||||
|
<meta http-equiv="Content-Style-Type" content="text/css" />
|
||||||
|
<meta name="generator" content="AppFuse 2.0" /> <!-- leave this for stats please -->
|
||||||
|
<link rel="icon" href="/cm/images/favicon.ico"/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script type="text/javascript" src="/cm/struts/js/base/jquery-1.7.2.min.js"></script>
|
||||||
|
<script type="text/javascript" src="/cm/struts/js/base/jquery.ui.core.min.js?s2j=3.3.3"></script>
|
||||||
|
<script type="text/javascript" src="/cm/struts/js/plugins/jquery.subscribe.min.js"></script>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="/cm/struts/js/struts2/jquery.struts2-3.3.3.min.js"></script>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function() {
|
||||||
|
jQuery.struts2_jquery.version="3.3.3";
|
||||||
|
jQuery.scriptPath = "/cm/struts/";
|
||||||
|
jQuery.struts2_jquery.gridLocal = "en";
|
||||||
|
jQuery.struts2_jquery.timeLocal = "en";
|
||||||
|
jQuery.ajaxSettings.traditional = true;
|
||||||
|
|
||||||
|
jQuery.ajaxSetup ({
|
||||||
|
cache: false
|
||||||
|
});
|
||||||
|
|
||||||
|
jQuery.struts2_jquery.require("js/struts2/jquery.ui.struts2-3.3.3.min.js");
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<link id="jquery_theme_link" rel="stylesheet" href="/cm/struts/themes/ui-lightness/jquery-ui.css?s2j=3.3.3" type="text/css"/>
|
||||||
|
|
||||||
|
|
||||||
|
<title>Transfer | </title>
|
||||||
|
|
||||||
|
<link rel="stylesheet" type="text/css" media="all" href="/cm/styles/cm/theme.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" media="print" href="/cm/styles/cm/print.css" />
|
||||||
|
|
||||||
|
<script type="text/javascript" src="/cm/scripts/global.js"></script>
|
||||||
|
<script type="text/javascript" src="/cm/scripts/clipboard.js"></script>
|
||||||
|
<script type="text/javascript" src="/cm/scripts/jquery.blockUI.js"></script>
|
||||||
|
<script type="text/javascript" src="/cm/scripts/date.format.js"></script>
|
||||||
|
|
||||||
|
<meta name="heading" content="Transfer"/>
|
||||||
|
<meta name="menu" content="CMDepositWithdrawal"/>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
function submitForm(){
|
||||||
|
document.getElementById("button_transfer").disabled = true;
|
||||||
|
document.transferForm.submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
function searchUser(){
|
||||||
|
document.transferForm.action = "searchTransferUser";
|
||||||
|
document.transferForm.submit();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script language="JavaScript">
|
||||||
|
function readCookie(name){
|
||||||
|
return(document.cookie.match('(^|; )'+name+'=([^;]*)')||0)[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
//document.onscroll= document.cookie='ypos=' + window.pageYOffset;
|
||||||
|
|
||||||
|
$(window).scroll(function () {
|
||||||
|
document.cookie = 'ypos=' + getYOffset();
|
||||||
|
});
|
||||||
|
|
||||||
|
function getYOffset() {
|
||||||
|
var pageY;
|
||||||
|
if(typeof(window.pageYOffset)=='number') {
|
||||||
|
pageY=window.pageYOffset;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pageY=document.documentElement.scrollTop;
|
||||||
|
}
|
||||||
|
return pageY;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body onload="window.scrollTo(0,readCookie('ypos'));">
|
||||||
|
|
||||||
|
<div id="page">
|
||||||
|
<div id="header" class="clearfix">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- taglib uri="/struts-dojo-tags" prefix="sx" -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div id="branding">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0">
|
||||||
|
<tr>
|
||||||
|
<td><span id="spanTime" class="text-hdr-time-11"></span></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div id="scrollingMsg">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" width="100%">
|
||||||
|
<tr>
|
||||||
|
<td><marquee behavior="scroll" direction="left" scrollamount="2" onmouseover="this.stop();" onmouseout="this.start();">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CM C/S Wsap: +601156938483
|
||||||
|
|
||||||
|
Special Draw 28.10.2025
|
||||||
|
|
||||||
|
Bayaran Baru(3600 - 5100)
|
||||||
|
|
||||||
|
CM Wsap: +601156938483 | FB:www.facebook.com/cmcashmarket
|
||||||
|
Web:www.cmcashmarket.net
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</marquee>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div id="branding2">
|
||||||
|
|
||||||
|
<strong><span class="text-hdr-time-11">Welcome!, 13c4069</span></strong>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a id="english" href="mainMenu?locale=en"><img height="10" width="16" src="/cm/images/hdr_lag_en.gif"></a> <a id="chinese" href="mainMenu?locale=zh"><img height="10" width="16" src="/cm/images/hdr_lag_cn.gif"></a>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div id="header-login">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="content" class="clearfix">
|
||||||
|
<div id="main">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- taglib uri="/struts-dojo-tags" prefix="sx" -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- taglib uri="/struts-dojo-tags" prefix="sx" -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<form id="transferForm" method="post" action="saveTransfer" name="transferForm">
|
||||||
|
<input type="hidden" name="struts.token.name" value="token" />
|
||||||
|
<input type="hidden" name="token" value="IGMNWENN2PM86EB7X30UG781VK1N3VDJ" />
|
||||||
|
|
||||||
|
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||||
|
<tr>
|
||||||
|
<td height="40" bgcolor="#FFFFFF">
|
||||||
|
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||||
|
<tr>
|
||||||
|
<td width="20"> </td>
|
||||||
|
<td align="left" class="text-tt-18">Transfer</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td height="54" bgcolor="#f3f3f3" align="center">
|
||||||
|
<br>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<table id="depositTable" class="searchContent" border="0" style="width: 50%">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="bold" width="20%">Username : </td>
|
||||||
|
<td>
|
||||||
|
<input type="text" class="text medium" id="username" value="wby321" name="username" readonly="readonly">
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="bold" width="20%">Name : </td>
|
||||||
|
<td>
|
||||||
|
<input type="text" class="text medium" id="name" value="Danny" name="name" readonly="readonly">
|
||||||
|
<input id="toUserId" type="hidden" value="6RbBr1holqKIJb6N1XzJGA==" name="toUserId">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="bold" width="20%">Amount : </td>
|
||||||
|
<td>
|
||||||
|
<input type="text" class="text medium numberOnly" id="amount" value="" name="amount">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="bold" width="20%">Security Pin : </td>
|
||||||
|
<td>
|
||||||
|
<input type="password" class="text medium" id="securityPin" value="" name="securityPin">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="bold" width="20%"></td>
|
||||||
|
<td>
|
||||||
|
<input id="button_transfer" class="button" type="submit" onclick="javascript:submitForm();return false;" value="Transfer" name="button.transfer">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(".numberOnly").bind("keyup paste", function(){
|
||||||
|
var val = $(this).val();
|
||||||
|
if(isNaN(val)){
|
||||||
|
val = val.replace(/[^0-9\.]/g, '');
|
||||||
|
if(val.split('.').length>2) val =val.replace(/\.+$/,"");
|
||||||
|
|
||||||
|
this.value = val;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
-->
|
||||||
|
<div id="nav">
|
||||||
|
<div class="wrapper">
|
||||||
|
<h2 class="accessibility">Navigation</h2>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- taglib uri="/struts-dojo-tags" prefix="sx" -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<table border="0" cellspacing="0" cellpadding="0" width="100%">
|
||||||
|
<tr>
|
||||||
|
<td class="bg-hdr-bar-blue" height="35px">
|
||||||
|
<div style="padding-left:30px; padding-right:30px">
|
||||||
|
<table width="100%" cellspacing="0" cellpadding="0" border="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td width="10%">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td width="90%" align="right">
|
||||||
|
<div id='cssmenu' class="menuList">
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/cm/mainMenu" title="Main Menu" class="text-mn-12">Main Menu</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li class="has-sub">
|
||||||
|
<a href="javascript:void(0)" title="Cash Wallet" class="current" class="text-mn-12">Cash Wallet</a>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/cm/transfer" title="Transfer" class="text-mn-12">Transfer</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="last">
|
||||||
|
<a href="/cm/history/transferTransactions" title="Transfer Transactions" class="text-mn-12">Transfer Transactions</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li class="has-sub">
|
||||||
|
<a href="javascript:void(0)" title="Reports" class="text-mn-12">Reports</a>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/cm/report/simpleWinLossDetail" title="Win Loss Report" class="text-mn-12">Win Loss Report</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/cm/report/betStatistic" title="Bet Statistic" class="text-mn-12">Bet Statistic</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/cm/report/drawResult" title="Draw Result" class="text-mn-12">Draw Result</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="last">
|
||||||
|
<a href="/cm/report/memberReport" title="Member Report" class="text-mn-12">Member Report</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li class="has-sub">
|
||||||
|
<a href="javascript:void(0)" title="Account" class="text-mn-12">Account</a>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/cm/showQrCode" title="QR Code" class="text-mn-12">QR Code</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/cm/register" title="Member Tree" class="text-mn-12">Member Tree</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/cm/changePassword" title="Change Password" class="text-mn-12">Change Password</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/cm/setSecurityPin" title="Change Security Pin" class="text-mn-12">Change Security Pin</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="last">
|
||||||
|
<a href="/cm/userPackageAction" title="Prize Package" class="text-mn-12">Prize Package</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/cm/logout" title="Logout" class="text-mn-12">Logout</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="bg-hdr-bar-shadow"> </td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<hr/>
|
||||||
|
</div><!-- end nav -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="footer" class="clearfix">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- taglib uri="/struts-dojo-tags" prefix="sx" -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<table width="100%" cellspacing="0" cellpadding="0" border="0">
|
||||||
|
<tr>
|
||||||
|
<td height="30" valign="top" bgcolor="#f6f6f6">
|
||||||
|
<table width="100%" cellspacing="0" cellpadding="0" border="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td height="25" width="30" valign="bottom"> </td>
|
||||||
|
<td valign="bottom" align="left" class="text-ftr-11">
|
||||||
|
Version 1.1.010
|
||||||
|
</td>
|
||||||
|
<td valign="bottom" align="right" class="text-ftr-11">
|
||||||
|
© 2017 <font color="#2881c1"><a href="https://cm99.net">cm99.net</a></font></td>
|
||||||
|
<td width="30" valign="bottom"> </td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
var timeServer = new Date(1759323694667);
|
||||||
|
//Users time
|
||||||
|
var timeLocal = new Date();
|
||||||
|
|
||||||
|
//Calculate the difference (returns milliseconds)
|
||||||
|
millDiff = timeLocal - timeServer;
|
||||||
|
|
||||||
|
//The ticking clock function
|
||||||
|
function TimeTick() {
|
||||||
|
//grab updated time
|
||||||
|
timeLocal = new Date();
|
||||||
|
//add time difference
|
||||||
|
timeLocal.setMilliseconds(timeLocal.getMilliseconds() - millDiff);
|
||||||
|
//display the value
|
||||||
|
// document.getElementById("spanTime").innerHTML = timeLocal.toLocaleFormat('%A, %d-%b-%Y %I:%M:%S%p');
|
||||||
|
document.getElementById("spanTime").innerHTML = timeLocal.format("dddd, dd-mmm-yyyy hh:MM:ssTT");
|
||||||
|
}
|
||||||
|
|
||||||
|
setInterval('TimeTick()', 500);
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
Loading…
x
Reference in New Issue
Block a user