bsk194889353 3 weeks ago
parent 245909ac25
commit 30321dca2f

@ -1,2 +0,0 @@
# web_game

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

@ -0,0 +1,2 @@
**/__pycache__
*.swp

@ -0,0 +1,464 @@
.
|-- 123.txt
|-- acapp
| |-- __init__.py
| |-- __pycache__
| | |-- __init__.cpython-38.pyc
| | |-- asgi.cpython-38.pyc
| | |-- settings.cpython-38.pyc
| | |-- urls.cpython-38.pyc
| | `-- wsgi.cpython-38.pyc
| |-- asgi.py
| |-- settings.py
| |-- urls.py
| `-- wsgi.py
|-- db.sqlite3
|-- game
| |-- __init__.py
| |-- __pycache__
| | |-- __init__.cpython-38.pyc
| | |-- admin.cpython-38.pyc
| | |-- apps.cpython-38.pyc
| | |-- channelsmiddleware.cpython-38.pyc
| | `-- routing.cpython-38.pyc
| |-- admin.py
| |-- apps.py
| |-- channelsmiddleware.py
| |-- consumers
| | |-- __init__.py
| | |-- __pycache__
| | | `-- __init__.cpython-38.pyc
| | `-- multiplayer
| | |-- __init__.py
| | |-- __pycache__
| | | |-- __init__.cpython-38.pyc
| | | `-- index.cpython-38.pyc
| | `-- index.py
| |-- migrations
| | |-- 0001_initial.py
| | |-- 0002_rename_phote_player_photo.py
| | |-- 0003_player_openid.py
| | |-- 0004_player_score.py
| | |-- __init__.py
| | `-- __pycache__
| | |-- 0001_initial.cpython-38.pyc
| | |-- 0002_rename_phote_player_photo.cpython-38.pyc
| | |-- 0003_player_openid.cpython-38.pyc
| | |-- 0004_player_score.cpython-38.pyc
| | `-- __init__.cpython-38.pyc
| |-- models
| | |-- __init__.py
| | |-- __pycache__
| | | `-- __init__.cpython-38.pyc
| | `-- player
| | |-- __init__.py
| | |-- __pycache__
| | | |-- __init__.cpython-38.pyc
| | | `-- player.cpython-38.pyc
| | `-- player.py
| |-- routing.py
| |-- static
| | |-- css
| | | `-- game.css
| | |-- image
| | | |-- lxq.jpg
| | | |-- menu
| | | | |-- 123.gif
| | | | |-- background.gif
| | | | `-- ch.jpg
| | | |-- playground
| | | |-- settings
| | | | `-- acwing_logo.png
| | | |-- swgq.jpg
| | | |-- user_photo
| | | `-- zyj.jpg
| | `-- js
| | |-- dist
| | | `-- game.js
| | `-- src
| | |-- menu
| | | |-- cphoto
| | | | `-- base.js
| | | `-- zbase.js
| | |-- playground
| | | |-- ac_game_object
| | | | `-- zbase.js
| | | |-- chat_field
| | | | `-- zbase.js
| | | |-- game_map
| | | | `-- zbase.js
| | | |-- notice_board
| | | | `-- zbase.js
| | | |-- particle
| | | | `-- zbase.js
| | | |-- player
| | | | `-- zbase.js
| | | |-- score_board
| | | | `-- zbase.js
| | | |-- skill
| | | | `-- fireball
| | | | `-- zbase.js
| | | |-- socket
| | | | `-- multiplayer
| | | | `-- zbase.js
| | | `-- zbase.js
| | |-- settings
| | | `-- zbase.js
| | `-- zbase.js
| |-- templates
| | |-- menu
| | | |-- new.html
| | | |-- profile.html
| | | `-- ranklist\ html
| | |-- multiends
| | | `-- web.html
| | |-- plaground
| | `-- settings
| |-- tests.py
| |-- urls
| | |-- __init__.py
| | |-- __pycache__
| | | |-- __init__.cpython-38.pyc
| | | `-- index.cpython-38.pyc
| | |-- index.py
| | |-- menu
| | | |-- __init__.py
| | | |-- __pycache__
| | | | |-- __init__.cpython-38.pyc
| | | | `-- index.cpython-38.pyc
| | | `-- index.py
| | |-- playground
| | | |-- __init__.py
| | | |-- __pycache__
| | | | |-- __init__.cpython-38.pyc
| | | | `-- index.cpython-38.pyc
| | | `-- index.py
| | `-- settings
| | |-- __init__.py
| | |-- __pycache__
| | | |-- __init__.cpython-38.pyc
| | | `-- index.cpython-38.pyc
| | |-- acwing
| | | |-- __init__.py
| | | |-- __pycache__
| | | | |-- __init__.cpython-38.pyc
| | | | `-- index.cpython-38.pyc
| | | `-- index.py
| | `-- index.py
| `-- views
| |-- __init__.py
| |-- __pycache__
| | |-- __init__.cpython-38.pyc
| | `-- index.cpython-38.pyc
| |-- index.py
| |-- menu
| | `-- __init__.py
| |-- playground
| | `-- __init__.py
| `-- settings
| |-- __init__.py
| |-- __pycache__
| | |-- __init__.cpython-38.pyc
| | |-- getinfo.cpython-38.pyc
| | |-- login.cpython-38.pyc
| | |-- logout.cpython-38.pyc
| | |-- ranklist.cpython-38.pyc
| | `-- register.cpython-38.pyc
| |-- acwing
| | |-- __init__.py
| | |-- __pycache__
| | | `-- __init__.cpython-38.pyc
| | |-- acapp
| | | |-- __init__.py
| | | |-- __pycache__
| | | | |-- __init__.cpython-38.pyc
| | | | |-- apply_code.cpython-38.pyc
| | | | `-- receive_code.cpython-38.pyc
| | | |-- apply_code.py
| | | `-- receive_code.py
| | `-- web
| | |-- __init__.py
| | |-- __pycache__
| | | |-- __init__.cpython-38.pyc
| | | |-- apply_code.cpython-38.pyc
| | | `-- receive_code.cpython-38.pyc
| | |-- apply_code.py
| | `-- receive_code.py
| |-- getinfo.py
| |-- ranklist.py
| `-- register.py
|-- manage.py
|-- match_system
| |-- __init__.py
| |-- __pycache__
| | `-- __init__.cpython-38.pyc
| |-- src
| | |-- __init__.py
| | |-- __pycache__
| | | `-- __init__.cpython-38.pyc
| | |-- main.py
| | `-- match_server
| | |-- __init__.py
| | |-- __pycache__
| | | `-- __init__.cpython-38.pyc
| | `-- match_service
| | |-- Match-remote
| | |-- Match.py
| | |-- __init__.py
| | |-- __pycache__
| | | |-- Match.cpython-38.pyc
| | | |-- __init__.cpython-38.pyc
| | | `-- ttypes.cpython-38.pyc
| | |-- constants.py
| | `-- ttypes.py
| `-- thrift
| `-- match.thrift
|-- readme.md
|-- scripts
| |-- compress_game_js.sh
| `-- uwsgi.ini
|-- static
| |-- admin
| | |-- css
| | | |-- autocomplete.css
| | | |-- base.css
| | | |-- changelists.css
| | | |-- dark_mode.css
| | | |-- dashboard.css
| | | |-- fonts.css
| | | |-- forms.css
| | | |-- login.css
| | | |-- nav_sidebar.css
| | | |-- responsive.css
| | | |-- responsive_rtl.css
| | | |-- rtl.css
| | | |-- vendor
| | | | `-- select2
| | | | |-- LICENSE-SELECT2.md
| | | | |-- select2.css
| | | | `-- select2.min.css
| | | `-- widgets.css
| | |-- fonts
| | | |-- LICENSE.txt
| | | |-- README.txt
| | | |-- Roboto-Bold-webfont.woff
| | | |-- Roboto-Light-webfont.woff
| | | `-- Roboto-Regular-webfont.woff
| | |-- img
| | | |-- LICENSE
| | | |-- README.txt
| | | |-- calendar-icons.svg
| | | |-- gis
| | | | |-- move_vertex_off.svg
| | | | `-- move_vertex_on.svg
| | | |-- icon-addlink.svg
| | | |-- icon-alert.svg
| | | |-- icon-calendar.svg
| | | |-- icon-changelink.svg
| | | |-- icon-clock.svg
| | | |-- icon-deletelink.svg
| | | |-- icon-no.svg
| | | |-- icon-unknown-alt.svg
| | | |-- icon-unknown.svg
| | | |-- icon-viewlink.svg
| | | |-- icon-yes.svg
| | | |-- inline-delete.svg
| | | |-- search.svg
| | | |-- selector-icons.svg
| | | |-- sorting-icons.svg
| | | |-- tooltag-add.svg
| | | `-- tooltag-arrowright.svg
| | `-- js
| | |-- SelectBox.js
| | |-- SelectFilter2.js
| | |-- actions.js
| | |-- admin
| | | |-- DateTimeShortcuts.js
| | | `-- RelatedObjectLookups.js
| | |-- autocomplete.js
| | |-- calendar.js
| | |-- cancel.js
| | |-- change_form.js
| | |-- collapse.js
| | |-- core.js
| | |-- filters.js
| | |-- inlines.js
| | |-- jquery.init.js
| | |-- nav_sidebar.js
| | |-- popup_response.js
| | |-- prepopulate.js
| | |-- prepopulate_init.js
| | |-- theme.js
| | |-- urlify.js
| | `-- vendor
| | |-- jquery
| | | |-- LICENSE.txt
| | | |-- jquery.js
| | | `-- jquery.min.js
| | |-- select2
| | | |-- LICENSE.md
| | | |-- i18n
| | | | |-- af.js
| | | | |-- ar.js
| | | | |-- az.js
| | | | |-- bg.js
| | | | |-- bn.js
| | | | |-- bs.js
| | | | |-- ca.js
| | | | |-- cs.js
| | | | |-- da.js
| | | | |-- de.js
| | | | |-- dsb.js
| | | | |-- el.js
| | | | |-- en.js
| | | | |-- es.js
| | | | |-- et.js
| | | | |-- eu.js
| | | | |-- fa.js
| | | | |-- fi.js
| | | | |-- fr.js
| | | | |-- gl.js
| | | | |-- he.js
| | | | |-- hi.js
| | | | |-- hr.js
| | | | |-- hsb.js
| | | | |-- hu.js
| | | | |-- hy.js
| | | | |-- id.js
| | | | |-- is.js
| | | | |-- it.js
| | | | |-- ja.js
| | | | |-- ka.js
| | | | |-- km.js
| | | | |-- ko.js
| | | | |-- lt.js
| | | | |-- lv.js
| | | | |-- mk.js
| | | | |-- ms.js
| | | | |-- nb.js
| | | | |-- ne.js
| | | | |-- nl.js
| | | | |-- pl.js
| | | | |-- ps.js
| | | | |-- pt-BR.js
| | | | |-- pt.js
| | | | |-- ro.js
| | | | |-- ru.js
| | | | |-- sk.js
| | | | |-- sl.js
| | | | |-- sq.js
| | | | |-- sr-Cyrl.js
| | | | |-- sr.js
| | | | |-- sv.js
| | | | |-- th.js
| | | | |-- tk.js
| | | | |-- tr.js
| | | | |-- uk.js
| | | | |-- vi.js
| | | | |-- zh-CN.js
| | | | `-- zh-TW.js
| | | |-- select2.full.js
| | | `-- select2.full.min.js
| | `-- xregexp
| | |-- LICENSE.txt
| | |-- xregexp.js
| | `-- xregexp.min.js
| |-- css
| | `-- game.css
| |-- image
| | |-- lxq.jpg
| | |-- menu
| | | |-- 1.gif
| | | |-- 123.gif
| | | |-- background.gif
| | | `-- ch.jpg
| | |-- settings
| | | `-- acwing_logo.png
| | |-- swgq.jpg
| | |-- user_photo
| | | |-- lxq.jpg
| | | `-- zyj.jpg
| | `-- zyj.jpg
| |-- js
| | |-- dist
| | | |-- game.js
| | | `-- game.jspython3
| | `-- src
| | |-- menu
| | | |-- cphoto
| | | | `-- base.js
| | | |-- ranklist
| | | `-- zbase.js
| | |-- playground
| | | |-- ac_game_object
| | | | `-- zbase.js
| | | |-- chat_field
| | | | `-- zbase.js
| | | |-- game_map
| | | | `-- zbase.js
| | | |-- notice_board
| | | | `-- zbase.js
| | | |-- particle
| | | | `-- zbase.js
| | | |-- player
| | | | `-- zbase.js
| | | |-- score_board
| | | | `-- zbase.js
| | | |-- skill
| | | | `-- fireball
| | | | `-- zbase.js
| | | |-- socket
| | | | `-- multiplayer
| | | | `-- zbase.js
| | | `-- zbase.js
| | |-- settings
| | | `-- zbase.js
| | `-- zbase.js
| `-- rest_framework
| |-- css
| | |-- bootstrap-theme.min.css
| | |-- bootstrap-theme.min.css.map
| | |-- bootstrap-tweaks.css
| | |-- bootstrap.min.css
| | |-- bootstrap.min.css.map
| | |-- default.css
| | |-- font-awesome-4.0.3.css
| | `-- prettify.css
| |-- docs
| | |-- css
| | | |-- base.css
| | | |-- highlight.css
| | | `-- jquery.json-view.min.css
| | |-- img
| | | |-- favicon.ico
| | | `-- grid.png
| | `-- js
| | |-- api.js
| | |-- highlight.pack.js
| | `-- jquery.json-view.min.js
| |-- fonts
| | |-- fontawesome-webfont.eot
| | |-- fontawesome-webfont.svg
| | |-- fontawesome-webfont.ttf
| | |-- fontawesome-webfont.woff
| | |-- glyphicons-halflings-regular.eot
| | |-- glyphicons-halflings-regular.svg
| | |-- glyphicons-halflings-regular.ttf
| | |-- glyphicons-halflings-regular.woff
| | `-- glyphicons-halflings-regular.woff2
| |-- img
| | |-- glyphicons-halflings-white.png
| | |-- glyphicons-halflings.png
| | `-- grid.png
| `-- js
| |-- ajax-form.js
| |-- bootstrap.min.js
| |-- coreapi-0.1.1.js
| |-- csrf.js
| |-- default.js
| |-- jquery-3.7.1.min.js
| |-- load-ajax-form.js
| `-- prettify-min.js
`-- terser
124 directories, 337 files

@ -0,0 +1,30 @@
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'acapp.settings')
django.setup()
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
from game.routing import websocket_urlpatterns
from channels.layers import get_channel_layer
from game.channelsmiddleware import JwtAuthMiddlewareStack
channel_layer = get_channel_layer()
application = ProtocolTypeRouter({
"http": get_asgi_application(),
"websocket": JwtAuthMiddlewareStack(URLRouter(websocket_urlpatterns))
})

@ -0,0 +1,203 @@
"""
Django settings for acapp project.
Generated by 'django-admin startproject' using Django 3.2.8.
For more information on this file, see
https://docs.djangoproject.com/en/3.2/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.2/ref/settings/
"""
import os
from pathlib import Path
from datetime import timedelta
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-11un1-%3!jwqsi2y4ljne)n$xz$o^43h!+1)o3(b57vcw9==gs'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ["60.205.142.48","app6641.acapp.acwing.com.cn"]
# Application definition
INSTALLED_APPS = [
'channels',
'game.apps.GameConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'rest_framework_simplejwt',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'acapp.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'acapp.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379/1',
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
},
},
}
# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/
STATIC_ROOT = os.path.join(BASE_DIR,'static')
STATIC_URL = '/static/'
MEDIA_ROOT = os.path.join(BASE_DIR,'media')
MEDIA_URL = '/media/'
# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
ASGI_APPLICATION = 'acapp.asgi.application'
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [("127.0.0.1", 6379)],
},
},
}
ROOM_CAPACITY = 3
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
)
}
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
'REFRESH_TOKEN_LIFETIME': timedelta(days=14),
'ROTATE_REFRESH_TOKENS': False,
'BLACKLIST_AFTER_ROTATION': False,
'UPDATE_LAST_LOGIN': False,
'ALGORITHM': 'HS256',
'SIGNING_KEY': "bsk1194889353",
'VERIFYING_KEY': None,
'AUDIENCE': None,
'ISSUER': None,
'JWK_URL': None,
'LEEWAY': 0,
'AUTH_HEADER_TYPES': ('Bearer',),
'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',
'USER_ID_FIELD': 'id',
'USER_ID_CLAIM': 'user_id',
'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule',
'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
'TOKEN_TYPE_CLAIM': 'token_type',
'TOKEN_USER_CLASS': 'rest_framework_simplejwt.models.TokenUser',
'JTI_CLAIM': 'jti',
'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
'SLIDING_TOKEN_LIFETIME': timedelta(minutes=5),
'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1),
}

@ -0,0 +1,22 @@
"""acapp URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.2/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('',include('game.urls.index')),
path('admin/', admin.site.urls),
]

@ -0,0 +1,16 @@
"""
WSGI config for acapp project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/3.2/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'acapp.settings')
application = get_wsgi_application()

Binary file not shown.

@ -0,0 +1,4 @@
from django.contrib import admin
from game.models.player.player import Player
# Register your models here.
admin.site.register(Player)

@ -0,0 +1,6 @@
from django.apps import AppConfig
class GameConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'game'

@ -0,0 +1,58 @@
"""General web socket middlewares
"""
from channels.db import database_sync_to_async
from django.contrib.auth import get_user_model
from django.contrib.auth.models import AnonymousUser
from rest_framework_simplejwt.exceptions import InvalidToken, TokenError
from rest_framework_simplejwt.tokens import UntypedToken
from rest_framework_simplejwt.authentication import JWTTokenUserAuthentication
from channels.middleware import BaseMiddleware
from channels.auth import AuthMiddlewareStack
from django.db import close_old_connections
from urllib.parse import parse_qs
from jwt import decode as jwt_decode
from django.conf import settings
@database_sync_to_async
def get_user(validated_token):
try:
user = get_user_model().objects.get(id=validated_token["user_id"])
# return get_user_model().objects.get(id=toke_id)
return user
except:
return AnonymousUser()
class JwtAuthMiddleware(BaseMiddleware):
def __init__(self, inner):
self.inner = inner
async def __call__(self, scope, receive, send):
# Close old database connections to prevent usage of timed out connections
close_old_connections()
# Try to authenticate the user
try:
# Get the token
token = parse_qs(scope["query_string"].decode("utf8"))["token"][0]
# This will automatically validate the token and raise an error if token is invalid
UntypedToken(token)
except:
# Token is invalid
scope["user"] = AnonymousUser()
else:
# Then token is valid, decode it
decoded_data = jwt_decode(token, settings.SIMPLE_JWT["SIGNING_KEY"], algorithms=["HS256"])
# Get the user using ID
scope["user"] = await get_user(validated_token=decoded_data)
return await super().__call__(scope, receive, send)
def JwtAuthMiddlewareStack(inner):
return JwtAuthMiddleware(AuthMiddlewareStack(inner))

@ -0,0 +1,176 @@
from channels.generic.websocket import AsyncWebsocketConsumer
import json
from django.conf import settings
from django.core.cache import cache
from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from match_system.src.match_server.match_service import Match
from game.models.player.player import Player
from channels.db import database_sync_to_async
class MultiPlayer(AsyncWebsocketConsumer):
async def connect(self):
user = self.scope['user']
print(user,user.is_authenticated)
if user.is_authenticated:
await self.accept()
else:
await self.close()
async def disconnect(self, close_code):
if hasattr(self,'room_name') and self.room_name:
await self.channel_layer.group_discard(self.room_name, self.channel_name);
async def create_player(self, data):
self.room_name = None
self.uuid = data['uuid']
# Make socket
transport = TSocket.TSocket('127.0.0.1', 9090)
# Buffering is critical. Raw sockets are very slow
transport = TTransport.TBufferedTransport(transport)
# Wrap in a protocol
protocol = TBinaryProtocol.TBinaryProtocol(transport)
# Create a client to use the protocol encoder
client = Match.Client(protocol)
def db_get_player():
return Player.objects.get(user__username=data['username'])
player = await database_sync_to_async(db_get_player)()
# Connect!
transport.open()
client.add_player(player.score, data['uuid'], data['username'], data['photo'], self.channel_name)
# Close!
transport.close()
async def group_send_event(self, data):
if not self.room_name:
keys = cache.keys('*%s*' % (self.uuid))
if keys:
self.room_name = keys[0]
await self.send(text_data=json.dumps(data))
async def move_to(self, data):
await self.channel_layer.group_send(
self.room_name,
{
'type': "group_send_event",
'event': "move_to",
'uuid': data['uuid'],
'tx': data['tx'],
'ty': data['ty'],
}
)
async def shoot_fireball(self, data):
await self.channel_layer.group_send(
self.room_name,
{
'type': "group_send_event",
'event': "shoot_fireball",
'uuid': data['uuid'],
'tx': data['tx'],
'ty': data['ty'],
'ball_uuid': data['ball_uuid'],
}
)
async def attack(self, data):
if not self.room_name:
return
players = cache.get(self.room_name)
if not players:
return
for player in players:
if player['uuid'] == data['attackee_uuid']:
player['hp'] -= 25
remain_cnt = 0
for player in players:
if player['hp'] > 0:
remain_cnt += 1
if remain_cnt > 1:
if self.room_name:
cache.set(self.room_name, players, 3600)
else:
def db_update_player_score(username, score):
player = Player.objects.get(user__username=username)
player.score += score
player.save()
for player in players:
if player['hp'] <= 0:
await database_sync_to_async(db_update_player_score)(player['username'], -10)
print("down")
else:
await database_sync_to_async(db_update_player_score)(player['username'], 10)
print("up")
await self.channel_layer.group_send(
self.room_name,
{
'type': "group_send_event",
'event': "attack",
'uuid': data['uuid'],
'attackee_uuid': data['attackee_uuid'],
'x': data['x'],
'y': data['y'],
'angle': data['angle'],
'damage': data['damage'],
'ball_uuid': data['ball_uuid'],
}
)
async def blink(self, data):
await self.channel_layer.group_send(
self.room_name,
{
'type': "group_send_event",
'event': "blink",
'uuid': data['uuid'],
'tx': data['tx'],
'ty': data['ty'],
}
)
async def message(self, data):
await self.channel_layer.group_send(
self.room_name,
{
'type': "group_send_event",
'event': "message",
'uuid': data['uuid'],
'username': data['username'],
'text': data['text'],
}
)
async def receive(self, text_data):
data = json.loads(text_data)
event = data['event']
if event == "create_player":
await self.create_player(data)
elif event == "move_to":
await self.move_to(data)
elif event == "shoot_fireball":
await self.shoot_fireball(data)
elif event == "attack":
await self.attack(data)
elif event == "blink":
await self.blink(data)
elif event == "message":
await self.message(data)

@ -0,0 +1,25 @@
# Generated by Django 3.2.8 on 2024-05-15 08:40
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Player',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('phote', models.URLField(blank=True, max_length=256)),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]

@ -0,0 +1,18 @@
# Generated by Django 3.2.8 on 2024-05-15 08:47
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('game', '0001_initial'),
]
operations = [
migrations.RenameField(
model_name='player',
old_name='phote',
new_name='photo',
),
]

@ -0,0 +1,18 @@
# Generated by Django 3.2.8 on 2024-06-11 13:56
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('game', '0002_rename_phote_player_photo'),
]
operations = [
migrations.AddField(
model_name='player',
name='openid',
field=models.CharField(blank=True, default='', max_length=50, null=True),
),
]

@ -0,0 +1,18 @@
# Generated by Django 3.2.8 on 2024-08-03 02:43
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('game', '0003_player_openid'),
]
operations = [
migrations.AddField(
model_name='player',
name='score',
field=models.IntegerField(default=1500),
),
]

@ -0,0 +1,11 @@
from django.db import models
from django.contrib.auth.models import User
class Player (models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
photo = models.URLField(max_length=256,blank=True)
openid = models.CharField(default="",max_length=50,blank =True,null=True)
score = models.IntegerField(default = 1500)
def __str__(self):
return str(self.user)

@ -0,0 +1,5 @@
from django.urls import path
from game.consumers.multiplayer.index import MultiPlayer
websocket_urlpatterns = [
path("wss/multiplayer/",MultiPlayer.as_asgi(),name = "wss_multiplayer"),
]

@ -0,0 +1,203 @@
.ac-game-settings{
width: 100%;
height: 100%;
background-image: url("/static/image/menu/123.gif");
background-size: 100% 100%;
user-select: none;
}
.ac-game-settings-login{
height: 50vh;
width: 20vw;
position: relative;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
background-color: rgba(0,0,0,0.7);
border-radius: 5px;
}
.ac-game-settings-register{
height: 55vh;
width: 20vw;
position: relative;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
background-color: rgba(0,0,0,0.7);
}
.ac-game-settings-title {
color: white;
font-size: 3vh;
text-align: center;
height: 7vh;
padding-top:2vh;
margin-bottom:2vh;
}
.ac-game-settings-password{
display:block;
height:7vh;
}
.ac-game-settings-submit{
display:block;
height:7vh;
}
.ac-game-settings-username{
display: block;
height:7vh;
}
.ac-game-settings-item {
width:100%;
height:100%;
}
.ac-game-settings-item > input{
width:90%;
line-height:3vh;
position: relative;
top:50%;
left:50%;
transform: translate(-50%,-50%);
}
.ac-game-settings-item > button{
color:white;
width:90%;
line-height:3vh;
position: relative;
top:50%;
left:50%;
transform: translate(-50%,-50%);
background-color:#4CAF50;
border-radius:5px;
}
.ac-game-settings-error-message{
color:red;
font-size:2vh;
display: inline;
float:left;
padding-left:2vw;
}
.ac-game-settings-option{
color:white;
font-size:2vh;
display:inline;
float:right;
padding-right:1vw;
cursor:pointer;
}
.ac-game-settings-acwing{
display:block;
height:7vh;
}
.ac-game-settings-acwing > img {
position: relative;
top:50%;
left:50%;
transform: translate(-50%,-50%);
cursor:pointer;
clear:both;
}
.ac-game-settings-acwing > div{
color:white;
font-size:1.5vh;
text-align:center;
}
.ac-game-menu{
width: 100%;
height: 100%;
background-image: url("/static/image/menu/background.gif");
background-size: 100% 100%;
user-select: none;
}
.ac-game-menu-field{
width: 20vw;
position: relative;
top: 20%;
left: 20%;
}
.ac-game-menu-field-item{
color: white;
height: 7vh;
width: 50vw;
font-size: 5vh;
font-style: italic;
padding: 2vh;
text-align: center;
background-color:rgba(39,21,28,0.6);
border-radius: 10px;
letter-spacing: 0.5vw;
cursor: pointer;
}
.ac-game-menu-field-item:hover{
transform: scale(1.2);
transition: 100ms;
}
.ac-game-playground{
height:100%;
width: 100%;
user-select:none;
background-color:grey;
}
.ac-game-playground > canvas {
position: relative;
top:50%;
left:50%;
transform: translate(-50%,-50%);
}
.ac-game-chat-field-history {
position: absolute;
top: 66%;
left: 20%;
transform: translate(-50%, -50%);
width: 20%;
height: 32%;
color: white;
font-size: 2vh;
padding: 5px;
overflow: auto;
}
.ac-game-chat-field-history::-webkit-scrollbar {
width: 0;
}
.ac-game-chat-field-input {
position: absolute;
top: 86%;
left: 20%;
transform: translate(-50%, -50%);
width: 20%;
height: 3vh;
color: white;
font-size: 2vh;
background-color: rgba(222,225,230, 0.2);
}
.single-rule{
color:white;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

File diff suppressed because it is too large Load Diff

@ -0,0 +1,30 @@
class Cphoto {
constructor(root){
this.root = root;
this.$cphoto = $(`<div style="background-color: black; color: white; padding: 20px;width: 100%; height:100%;z-index : 9999"></div>`);
//this.hide();
//this.root.$ac_game.append(this.$cphoto);
this.start();
}
start(){
}
hide(){
this.$cphoto.hide();
}
show(){
this.$cphoto.show();
}
}

@ -0,0 +1,192 @@
class AcGameMenu {
constructor(root) {
this.root = root;
this.$menu = $(`
<div class="ac-game-menu">
<div class="ac-game-menu-field">
<div class="ac-game-menu-field-item ac-game-menu-field-item-cphoto">
头像选择
</div>
<div class="ac-game-menu-field-item ac-game-menu-field-item-single-mode">
单人模式
</div>
<br>
<div class="ac-game-menu-field-item ac-game-menu-field-item-multi-mode">
多人模式
</div>
<div class="ac-game-menu-field-item ac-game-menu-field-item-ranklist">
天梯榜
</div>
<br>
<div class="ac-game-menu-field-item ac-game-menu-field-item-settings">
退出
</div>
</div>
</div>
`);
this.$menu.hide();
this.root.$ac_game.append(this.$menu);
this.$single_mode = this.$menu.find('.ac-game-menu-field-item-single-mode');
this.$multi_mode = this.$menu.find('.ac-game-menu-field-item-multi-mode');
this.$settings = this.$menu.find('.ac-game-menu-field-item-settings');
this.$cphoto_button = this.$menu.find('.ac-game-menu-field-item-cphoto');
this.$ranklist_button = this.$menu.find('.ac-game-menu-field-item-ranklist')
this.start();
}
start() {
this.add_listening_events();
}
add_listening_events() {
let outer = this;
this.$single_mode.click(function () {
outer.hide();
outer.root.playground.show("single mode");
});
this.$multi_mode.click(function () {
outer.hide();
outer.root.playground.show("multi mode");
});
this.$settings.click(function () {
outer.root.settings.logout_on_remote();
});
this.$cphoto_button.click(function () {
window.location.href = '/photo';
console.log(outer.root.settings.photo);
});
this.$ranklist_button.click(function () {
$.ajax({
url: "https://app6641.acapp.acwing.com.cn/settings/ranklist/",
type: "GET",
headers: {
'Authorization': "Bearer " + outer.root.access,
},
success: function (resp) {
// 清空当前页面内容
document.body.innerHTML = `
<div style="text-align: center; margin-top: 20px;">
<button id="logout-button" style="
padding: 10px 20px;
background-color: #f44336;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
margin-bottom: 20px;
">退出</button>
<h1>用户排名</h1>
</div>
<table style="
width: 60%;
margin: auto;
border-collapse: collapse;
">
<thead>
<tr>
<th style="
padding: 10px;
border: 1px solid #ddd;
text-align: center;
">排名</th>
<th style="
padding: 10px;
border: 1px solid #ddd;
text-align: center;
">头像</th>
<th style="
padding: 10px;
border: 1px solid #ddd;
text-align: center;
">用户名</th>
<th style="
padding: 10px;
border: 1px solid #ddd;
text-align: center;
">分数</th>
</tr>
</thead>
<tbody id="ranklist-body">
<!-- 用户排名信息将通过 JavaScript 插入到这里 -->
</tbody>
</table>
`;
// 获取表格主体的 DOM 元素
const ranklistBody = document.getElementById('ranklist-body');
// 遍历用户数据并生成 HTML 行
resp.forEach((user, index) => {
const row = document.createElement('tr');
// 排名
const rankCell = document.createElement('td');
rankCell.textContent = index + 1;
rankCell.setAttribute("style", "padding: 10px; border: 1px solid #ddd; text-align: center;");
row.appendChild(rankCell);
// 头像
const photoCell = document.createElement('td');
const img = document.createElement('img');
img.src = user.photo;
img.alt = user.username;
img.setAttribute("style", "width: 50px; height: 50px; border-radius: 50%;");
photoCell.appendChild(img);
photoCell.setAttribute("style", "padding: 10px; border: 1px solid #ddd; text-align: center;");
row.appendChild(photoCell);
// 用户名
const usernameCell = document.createElement('td');
usernameCell.textContent = user.username;
usernameCell.setAttribute("style", "padding: 10px; border: 1px solid #ddd; text-align: center;");
row.appendChild(usernameCell);
// 分数
const scoreCell = document.createElement('td');
scoreCell.textContent = user.score;
scoreCell.setAttribute("style", "padding: 10px; border: 1px solid #ddd; text-align: center;");
row.appendChild(scoreCell);
// 将行添加到表格主体中
ranklistBody.appendChild(row);
});
// 添加“退出”按钮点击事件
document.getElementById('logout-button').addEventListener('click', () => {
window.location.href = "https://app6641.acapp.acwing.com.cn/"; // 将此路径替换为实际的注销页面路径
});
},
error: function (xhr, status, error) {
console.error("请求失败:", error);
alert("无法获取排名列表,请稍后重试。");
}
});
});
}
show() {
this.$menu.show();
}
hide() {
this.$menu.hide();
}
}

@ -0,0 +1,73 @@
let AC_GAME_OBJECTS = [];
class AcGameObject {
constructor() {
AC_GAME_OBJECTS.push(this);
this.has_called_start = false; // 是否执行过start函数
this.timedelta = 0; // 当前帧距离上一帧的时间间隔
this.uuid = this.create_uuid();
}
create_uuid() {
let res = "";
for(let i = 0;i < 8 ; i++){
let x = parseInt(Math.floor(Math.random()*10));
res += x;
}
return res;
}
start() { // 只会在第一帧执行一次
}
update() { // 每一帧均会执行一次
}
late_update(){
}
on_destroy() { // 在被销毁前执行一次
}
destroy() { // 删掉该物体
this.on_destroy();
for (let i = 0; i < AC_GAME_OBJECTS.length; i ++ ) {
if (AC_GAME_OBJECTS[i] === this) {
AC_GAME_OBJECTS.splice(i, 1);
break;
}
}
}
}
let last_timestamp;
let AC_GAME_ANIMATION = function(timestamp) {
for (let i = 0; i < AC_GAME_OBJECTS.length; i ++ ) {
let obj = AC_GAME_OBJECTS[i];
if (!obj.has_called_start) {
obj.start();
obj.has_called_start = true;
} else {
obj.timedelta = timestamp - last_timestamp;
obj.update();
}
}
for(let i = 0;i< AC_GAME_OBJECTS.length;i++){
let obj = AC_GAME_OBJECTS[i];
obj.late_update();
}
last_timestamp = timestamp;
requestAnimationFrame(AC_GAME_ANIMATION);
}
requestAnimationFrame(AC_GAME_ANIMATION);

@ -0,0 +1,97 @@
class ChatField{
constructor(playground){
console.log("chat");
this.playground = playground;
this.$history = $(`<div class = "ac-game-chat-field-history"></div>`)
this.$input = $(`<input type="text" class = "ac-game-chat-field-input">`)
this.$history.hide();
this.$input.hide();
this.playground.$playground.append(this.$history);
this.playground.$playground.append(this.$input);
this.start();
this.function_id = null;
}
start(){
this.add_listening_events();
}
add_listening_events(){
let outer =this;
this.$input.keydown(function(e){
if(e.which === 27){
outer.hide_input();
return false;
}else if (e.which === 13){
let username = outer.playground.root.settings.username;
let text = outer.$input.val();
if(text){
outer.$input.val("");
outer.add_message(username,text);
outer.playground.mps.send_message(text);
}
return false;
}
});
}
show_history(){
let outer = this;
this.$history.fadeIn();
if(this.function_id){
clearTimeout(this.function_id);
}
this.function_id = setTimeout(function(){
outer.$history.fadeOut();
outer.function_id = null;
},3000);
}
show_input(){
this.show_history();
this.$input.show();
this.$input.focus();
}
hide_input(){
this.$input.hide();
this.playground.game_map.$canvas.focus();
}
add_message(username,text){
this.show_history();
let message = `[${username}]${text}`
this.$history.append(this.render_message(message));
this.$history.scrollTop(this.$history[0].scrollHeight);
}
render_message(message){
return $(`<div>${message}</div>`);
}
}

@ -0,0 +1,32 @@
class GameMap extends AcGameObject{
constructor(playground){
super();
this.playground=playground;
this.$canvas = $(`<canvas tabindex = 0></canvas>`);
this.ctx = this.$canvas[0].getContext('2d');
this.ctx.canvas.width = this.playground.width;
this.ctx.canvas.height = this.playground.height;
this.playground.$playground.append(this.$canvas);
}
start(){
this.$canvas.focus();
}
resize(){
this.ctx.canvas.width = this.playground.width;
this.ctx.canvas.height = this.playground.height;
this.ctx.fillStyle = "rgba(0,0,0)";
this.ctx.fillRect(0,0,this.ctx.canvas.width,this.ctx.canvas.height);
}
update(){
this.render();
}
render(){
this.ctx.fillStyle = "rgba(0,0,0,0.2)";
this.ctx.fillRect(0,0,this.ctx.canvas.width,this.ctx.canvas.height);
}
}

@ -0,0 +1,28 @@
class NoticeBoard extends AcGameObject {
constructor(playground) {
super();
this.playground = playground;
this.ctx = this.playground.game_map.ctx;
this.text = "已就绪0人";
}
start() {
}
write(text) {
this.text = text;
}
update() {
this.render();
}
render() {
this.ctx.font = "20px serif";
this.ctx.fillStyle = "white";
this.ctx.textAlign = "center";
this.ctx.fillText(this.text, this.playground.width / 2, 20);
}
}

@ -0,0 +1,42 @@
class Particle extends AcGameObject{
constructor(playground,x,y,radius,vx,vy,color,speed,move_length){
super();
this.playground = playground;
this.x = x;
this.y = y;
this.radius = radius;
this.vx= vx;
this.vy = vy;
this.color = color;
this.speed = speed;
this.ctx = this.playground.game_map.ctx;
this.fraction = 0.9;
this.eps = 0.01;
this.move_length = move_length;
}
start(){
}
update(){
if(this.move_length< this.eps||this.speed< this.eps){
this.destroy();
return false;
}
let moved = Math.min(this.move_length,this.speed*this.timedelta/1000);
this.x += this.vx*moved;
this.y += this.vy*moved;
this.speed *= this.fraction;
this.move_length -= moved;
this.render();
}
render(){
let scale = this.playground.scale;
this.ctx.beginPath();
this.ctx.arc(this.x * scale,this.y * scale,this.radius * scale,0,Math.PI * 2,false);
this.ctx.fillStyle = this.color;
this.ctx.fill();
}
}

@ -0,0 +1,364 @@
class Player extends AcGameObject {
constructor(playground, x, y, radius, color, speed, character, username, photo) {
super();
this.playground = playground;
this.ctx = this.playground.game_map.ctx;
this.x = x;
this.y = y;
this.vx = 0;
this.vy = 0;
this.damage_x = 0;
this.damage_y = 0;
this.damage_speed = 0;
this.move_length = 0;
this.radius = radius;
this.color = color;
this.speed = speed;
this.character = character;
this.username = username;
this.photo = photo;
this.eps = 0.01;
this.friction = 0.9;
this.spent_time = 0;
this.fireballs = [];
this.cur_skill = null;
if (this.character !== "robot") {
this.img = new Image();
this.img.src = this.photo;
}
if (this.character === "me") {
this.fireball_coldtime = 3; // 单位:秒
this.fireball_img = new Image();
this.fireball_img.src = "https://cdn.acwing.com/media/article/image/2021/12/02/1_9340c86053-fireball.png";
this.blink_coldtime = 5; // 单位:秒
this.blink_img = new Image();
this.blink_img.src = "https://cdn.acwing.com/media/article/image/2021/12/02/1_daccabdc53-blink.png";
}
}
start() {
this.playground.player_count ++ ;
console.log(this.playground.player_count);
this.playground.notice_board.write("匹配中");
if (this.playground.player_count >= 3) {
this.playground.state = "fighting";
this.playground.notice_board.write("Fighting");
}
if (this.character === "me") {
this.add_listening_events();
} else if (this.character === "robot") {
let tx = Math.random() * this.playground.width / this.playground.scale;
let ty = Math.random() * this.playground.height / this.playground.scale;
this.move_to(tx, ty);
}
}
add_listening_events() {
let outer = this;
this.playground.game_map.$canvas.on("contextmenu", function() {
return false;
});
this.playground.game_map.$canvas.mousedown(function(e) {
if (outer.playground.state !== "fighting")
return true;
const rect = outer.ctx.canvas.getBoundingClientRect();
if (e.which === 3) {
let tx = (e.clientX - rect.left) / outer.playground.scale;
let ty = (e.clientY - rect.top) / outer.playground.scale;
outer.move_to(tx, ty);
if (outer.playground.mode === "multi mode") {
outer.playground.mps.send_move_to(tx, ty);
}
} else if (e.which === 1) {
let tx = (e.clientX - rect.left) / outer.playground.scale;
let ty = (e.clientY - rect.top) / outer.playground.scale;
if (outer.cur_skill === "fireball") {
if (outer.fireball_coldtime > outer.eps)
return false;
let fireball = outer.shoot_fireball(tx, ty);
if (outer.playground.mode === "multi mode") {
outer.playground.mps.send_shoot_fireball(tx, ty, fireball.uuid);
}
} else if (outer.cur_skill === "blink") {
if (outer.blink_coldtime > outer.eps)
return false;
outer.blink(tx, ty);
if (outer.playground.mode === "multi mode") {
outer.playground.mps.send_blink(tx, ty);
}
}
outer.cur_skill = null;
}
});
this.playground.game_map.$canvas.keydown(function(e) {
console.log(e.which);
if(e.which === 13){
if(outer.playground.mode === "multi mode")
outer.playground.chat_field.show_input();//打开了聊天框
} else if (e.which === 27){
if(outer.playground.mode === "multi mode"){
outer.playground.chat_field.hide_input();
}
}
if (outer.playground.state !== "fighting")
return true;
if (e.which === 81) { // q
if (outer.fireball_coldtime > outer.eps)
return true;
outer.cur_skill = "fireball";
return false;
} else if (e.which === 70) { // f
if (outer.blink_coldtime > outer.eps)
return true;
outer.cur_skill = "blink";
return false;
}
});
}
shoot_fireball(tx, ty) {
let x = this.x, y = this.y;
let radius = 0.01;
let angle = Math.atan2(ty - this.y, tx - this.x);
let vx = Math.cos(angle), vy = Math.sin(angle);
let color = "orange";
let speed = 0.5;
let move_length = 1;
let fireball = new FireBall(this.playground, this, x, y, radius, vx, vy, color, speed, move_length, 0.01);
this.fireballs.push(fireball);
this.fireball_coldtime = 3;
return fireball;
}
destroy_fireball(uuid) {
for (let i = 0; i < this.fireballs.length; i ++ ) {
let fireball = this.fireballs[i];
if (fireball.uuid === uuid) {
fireball.destroy();
break;
}
}
}
blink(tx, ty) {
let d = this.get_dist(this.x, this.y, tx, ty);
d = Math.min(d, 0.8);
let angle = Math.atan2(ty - this.y, tx - this.x);
this.x += d * Math.cos(angle);
this.y += d * Math.sin(angle);
this.blink_coldtime = 5;
this.move_length = 0; // 闪现完停下来
}
get_dist(x1, y1, x2, y2) {
let dx = x1 - x2;
let dy = y1 - y2;
return Math.sqrt(dx * dx + dy * dy);
}
move_to(tx, ty) {
this.move_length = this.get_dist(this.x, this.y, tx, ty);
let angle = Math.atan2(ty - this.y, tx - this.x);
this.vx = Math.cos(angle);
this.vy = Math.sin(angle);
}
is_attacked(angle, damage) {
for (let i = 0; i < 20 + Math.random() * 10; i ++ ) {
let x = this.x, y = this.y;
let radius = this.radius * Math.random() * 0.1;
let angle = Math.PI * 2 * Math.random();
let vx = Math.cos(angle), vy = Math.sin(angle);
let color = this.color;
let speed = this.speed * 10;
let move_length = this.radius * Math.random() * 5;
new Particle(this.playground, x, y, radius, vx, vy, color, speed, move_length);
}
this.radius -= damage;
if (this.radius < this.eps) {
this.destroy();
return false;
}
this.damage_x = Math.cos(angle);
this.damage_y = Math.sin(angle);
this.damage_speed = damage * 100;
this.speed *= 0.8;
}
receive_attack(x, y, angle, damage, ball_uuid, attacker) {
attacker.destroy_fireball(ball_uuid);
this.x = x;
this.y = y;
this.is_attacked(angle, damage);
}
update() {
this.spent_time += this.timedelta / 1000;
this.update_win();
if (this.character === "me" && this.playground.state === "fighting") {
this.update_coldtime();
}
this.update_move();
this.render();
}
update_win(){
if(this.playground.state === "fighting" && this.character === "me" && this.playground.players.length === 1){
this.state = "over";
this.playground.score_board.win();
}
}
update_coldtime() {
this.fireball_coldtime -= this.timedelta / 1000;
this.fireball_coldtime = Math.max(this.fireball_coldtime, 0);
this.blink_coldtime -= this.timedelta / 1000;
this.blink_coldtime = Math.max(this.blink_coldtime, 0);
}
update_move() { // 更新玩家移动
if (this.character === "robot" && this.spent_time > 4 && Math.random() < 1 / 300.0) {
let player = this.playground.players[Math.floor(Math.random() * this.playground.players.length)];
let tx = player.x + player.speed * this.vx * this.timedelta / 1000 * 0.3;
let ty = player.y + player.speed * this.vy * this.timedelta / 1000 * 0.3;
this.shoot_fireball(tx, ty);
}
if (this.damage_speed > this.eps) {
this.vx = this.vy = 0;
this.move_length = 0;
this.x += this.damage_x * this.damage_speed * this.timedelta / 1000;
this.y += this.damage_y * this.damage_speed * this.timedelta / 1000;
this.damage_speed *= this.friction;
} else {
if (this.move_length < this.eps) {
this.move_length = 0;
this.vx = this.vy = 0;
if (this.character === "robot") {
let tx = Math.random() * this.playground.width / this.playground.scale;
let ty = Math.random() * this.playground.height / this.playground.scale;
this.move_to(tx, ty);
}
} else {
let moved = Math.min(this.move_length, this.speed * this.timedelta / 1000);
this.x += this.vx * moved;
this.y += this.vy * moved;
this.move_length -= moved;
}
}
}
render() {
let scale = this.playground.scale;
if (this.character !== "robot") {
this.ctx.save();
this.ctx.beginPath();
this.ctx.arc(this.x * scale, this.y * scale, this.radius * scale, 0, Math.PI * 2, false);
this.ctx.stroke();
this.ctx.clip();
this.ctx.drawImage(this.img, (this.x - this.radius) * scale, (this.y - this.radius) * scale, this.radius * 2 * scale, this.radius * 2 * scale);
this.ctx.restore();
} else {
this.ctx.beginPath();
this.ctx.arc(this.x * scale, this.y * scale, this.radius * scale, 0, Math.PI * 2, false);
this.ctx.fillStyle = this.color;
this.ctx.fill();
}
if (this.character === "me" && this.playground.state === "fighting") {
this.render_skill_coldtime();
}
}
render_skill_coldtime() {
let scale = this.playground.scale;
let x = 1.5, y = 0.9, r = 0.04;
this.ctx.save();
this.ctx.beginPath();
this.ctx.arc(x * scale, y * scale, r * scale, 0, Math.PI * 2, false);
this.ctx.stroke();
this.ctx.clip();
this.ctx.drawImage(this.fireball_img, (x - r) * scale, (y - r) * scale, r * 2 * scale, r * 2 * scale);
this.ctx.restore();
if (this.fireball_coldtime > 0) {
this.ctx.beginPath();
this.ctx.moveTo(x * scale, y * scale);
this.ctx.arc(x * scale, y * scale, r * scale, 0 - Math.PI / 2, Math.PI * 2 * (1 - this.fireball_coldtime / 3) - Math.PI / 2, true);
this.ctx.lineTo(x * scale, y * scale);
this.ctx.fillStyle = "rgba(0, 0, 255, 0.6)";
this.ctx.fill();
}
x = 1.62, y = 0.9, r = 0.04;
this.ctx.save();
this.ctx.beginPath();
this.ctx.arc(x * scale, y * scale, r * scale, 0, Math.PI * 2, false);
this.ctx.stroke();
this.ctx.clip();
this.ctx.drawImage(this.blink_img, (x - r) * scale, (y - r) * scale, r * 2 * scale, r * 2 * scale);
this.ctx.restore();
if (this.blink_coldtime > 0) {
this.ctx.beginPath();
this.ctx.moveTo(x * scale, y * scale);
this.ctx.arc(x * scale, y * scale, r * scale, 0 - Math.PI / 2, Math.PI * 2 * (1 - this.blink_coldtime / 5) - Math.PI / 2, true);
this.ctx.lineTo(x * scale, y * scale);
this.ctx.fillStyle = "rgba(0, 0, 255, 0.6)";
this.ctx.fill();
}
}
on_destroy() {
if (this.character === "me"){
if(this.playground.state === "fighting"){
this.playground.state = "over";
this.playground.score_board.lose();
}
}
for (let i = 0; i < this.playground.players.length; i ++ ) {
if (this.playground.players[i] === this) {
this.playground.players.splice(i, 1);
break;
}
}
}
}

@ -0,0 +1,64 @@
class ScoreBoard extends AcGameObject {
constructor(playground) {
super();
this.playground = playground;
this.ctx = this.playground.game_map.ctx;
this.state = null; // win: 胜利lose失败
this.win_img = new Image();
this.win_img.src = "https://cdn.acwing.com/media/article/image/2021/12/17/1_8f58341a5e-win.png";
this.lose_img = new Image();
this.lose_img.src = "https://cdn.acwing.com/media/article/image/2021/12/17/1_9254b5f95e-lose.png";
}
start() {
}
add_listening_events() {
let outer = this;
if(this.playground.game_map === null)
return;
let $canvas = this.playground.game_map.$canvas;
$canvas.on('click', function() {
outer.playground.hide();
outer.playground.root.menu.show();
});
}
win() {
this.state = "win";
let outer = this;
setTimeout(function() {
outer.add_listening_events();
}, 1000);
}
lose() {
this.state = "lose";
let outer = this;
setTimeout(function() {
outer.add_listening_events();
}, 1000);
}
late_update() {
this.render();
}
render() {
let len = this.playground.height / 2;
if (this.state === "win") {
this.ctx.drawImage(this.win_img, this.playground.width / 2 - len / 2, this.playground.height / 2 - len / 2, len, len);
} else if (this.state === "lose") {
this.ctx.drawImage(this.lose_img, this.playground.width / 2 - len / 2, this.playground.height / 2 - len / 2, len, len);
}
}
}

@ -0,0 +1,98 @@
class FireBall extends AcGameObject {
constructor(playground,player,x,y,radius,vx,vy,color,speed,move_length,damage){
super();
this.playground=playground;
this.ctx = this.playground.game_map.ctx;
this.player = player;
this.x = x;
this.y = y;
this.radius = radius;
this.vx = vx;
this.vy = vy;
this.color = color;
this.speed = speed ;
this.move_length = move_length;
this.eps = 0.01;
this.damage = damage;
}
start(){
}
update(){
if(this.move_length < this.eps){
this.destroy();
return false;
}
this.update_move();
if(this.player.charactr !== "enemy"){
this.update_attack();
}
this.render();
}
update_move(){
let moved = Math.min(this.move_length,this.speed * this.timedelta / 1000);
this.x += this.vx * moved;
this.y += this.vy * moved;
this.move_length -= moved;
}
update_attack(){
for ( let i=0;i<this.playground.players.length; i++ ){
let player = this.playground.players[i];
if(this.player !== player && this.is_collision(player)){
this.attack(player);
}
}
}
get_dist(x1,y1,x2,y2){
let dx= x1-x2;
let dy = y1-y2;
return Math.sqrt(dx*dx + dy*dy);
}
is_collision(obj){
let distance = this.get_dist(this.x,this.y,obj.x,obj.y);
if(distance < this.radius + obj.radius)
return true;
return false;
}
attack(player){
let angle = Math.atan2(player.y - this.y,player.x-this.x);
player.is_attacked(angle,this.damage);
if (this.playground.mode === "multi mode"){
console.log(this.damage);
this.playground.mps.send_attack(player.uuid,player.x,player.y,angle,this.damage,this.uuid);
}
this.destroy();
}
render(){
let scale = this.playground.scale
this.ctx.beginPath();
this.ctx.arc(this.x * scale, this.y * scale, this.radius * scale, 0,
Math.PI * 2, false); this.ctx.fillStyle = this.color;
this.ctx.fill(); }
on_destroy() {
let fireballs = this.player.fireballs;
for(let i=0;i<fireballs.length;i++)
if(fireballs[i] === this){
fireballs.splice(i,1);
break;
}
}
}

@ -0,0 +1,177 @@
class MultiPlayerSocket {
constructor(playground) {
this.playground = playground;
this.ws = new WebSocket("wss://app6641.acapp.acwing.com.cn/wss/multiplayer/?token=" + playground.root.access);
this.start();
}
start() {
this.receive();
}
receive () {
let outer = this;
this.ws.onmessage = function(e) {
let data = JSON.parse(e.data);
let uuid = data.uuid;
if (uuid === outer.uuid) return false;
let event = data.event;
if (event === "create_player") {
outer.receive_create_player(uuid, data.username, data.photo);
} else if (event === "move_to") {
outer.receive_move_to(uuid, data.tx, data.ty);
} else if (event === "shoot_fireball") {
outer.receive_shoot_fireball(uuid, data.tx, data.ty, data.ball_uuid);
} else if (event === "attack") {
outer.receive_attack(uuid, data.attackee_uuid, data.x, data.y, data.angle, data.damage, data.ball_uuid);
} else if (event === "blink") {
outer.receive_blink(uuid, data.tx, data.ty);
} else if(event === "message"){
outer.receive_message(uuid,data.text);
}
};
}
send_create_player(username, photo) {
let outer = this;
this.ws.send(JSON.stringify({
'event': "create_player",
'uuid': outer.uuid,
'username': username,
'photo': photo,
}));
}
get_player(uuid) {
let players = this.playground.players;
for (let i = 0; i < players.length; i ++ ) {
let player = players[i];
if (player.uuid === uuid)
return player;
}
return null;
}
receive_create_player(uuid, username, photo) {
let player = new Player(
this.playground,
this.playground.width / 2 / this.playground.scale,
0.5,
0.05,
"white",
0.15,
"enemy",
username,
photo,
);
player.uuid = uuid;
this.playground.players.push(player);
}
send_move_to(tx, ty) {
let outer = this;
this.ws.send(JSON.stringify({
'event': "move_to",
'uuid': outer.uuid,
'tx': tx,
'ty': ty,
}));
}
receive_move_to(uuid, tx, ty) {
let player = this.get_player(uuid);
if (player) {
player.move_to(tx, ty);
}
}
send_shoot_fireball(tx, ty, ball_uuid) {
let outer = this;
this.ws.send(JSON.stringify({
'event': "shoot_fireball",
'uuid': outer.uuid,
'tx': tx,
'ty': ty,
'ball_uuid': ball_uuid,
}));
}
receive_shoot_fireball(uuid, tx, ty, ball_uuid) {
let player = this.get_player(uuid);
if (player) {
let fireball = player.shoot_fireball(tx, ty);
fireball.uuid = ball_uuid;
}
}
send_attack(attackee_uuid, x, y, angle, damage, ball_uuid) {
let outer = this;
this.ws.send(JSON.stringify({
'event': "attack",
'uuid': outer.uuid,
'attackee_uuid': attackee_uuid,
'x': x,
'y': y,
'angle': angle,
'damage': damage,
'ball_uuid': ball_uuid,
}));
}
receive_attack(uuid, attackee_uuid, x, y, angle, damage, ball_uuid) {
let attacker = this.get_player(uuid);
let attackee = this.get_player(attackee_uuid);
if (attacker && attackee) {
attackee.receive_attack(x, y, angle, damage, ball_uuid, attacker);
}
}
send_blink(tx, ty) {
let outer = this;
this.ws.send(JSON.stringify({
'event': "blink",
'uuid': outer.uuid,
'tx': tx,
'ty': ty,
}));
}
receive_blink(uuid, tx, ty) {
let player = this.get_player(uuid);
if (player) {
player.blink(tx, ty);
}
}
send_message(text){
let outer = this;
this.ws.send(JSON.stringify({
'event':"message",
'uuid':outer.uuid,
'text':text,
}));
}
receive_message(uuid,text){
let player = this.get_player(uuid);
if(player){
player.playground.chat_field.add_message(player.username,text);
}
}
}

@ -0,0 +1,129 @@
class AcGamePlayground {
constructor(root){
this.root=root;
this.$playground = $(`<div class="ac-game-playground"></div>`);
this.hide();
this.root.$ac_game.append(this.$playground);
this.start();
}
get_random_color(){
let colors = ["blue","red","green","pink","grey"];
return colors[Math.floor(Math.random()*5)];
}
start(){
let outer=this;
let uuid = this.create_uuid();
$(window).on(`resize.${uuid}`,function(){
outer.resize();
});
if(this.root.AcWingOS){
this.root.AcWingOS.api.window.on_close(function(){
$(window).off(`resize.${uuid}`);
});
}
}
create_uuid() {
let res = "";
for(let i = 0;i < 8 ; i++){
let x = parseInt(Math.floor(Math.random()*10));
res += x;
}
return res;
}
resize(){
this.width = this.$playground.width();
this.height = this.$playground.height();
this.unit= Math.min(this.width/16,this.height/9);
this.width = this.unit * 16;
this.height = this.unit*9;
this.scale = this.height;
if(this.game_map)this.game_map.resize();
}
update(){
}
show(mode){
let outer = this;
this.$playground.show();
this.$playground.resize();
this.width= this.$playground.width();
this.height = this.$playground.height();
this.game_map = new GameMap(this);
this.resize();
this.players = [];
this.players.push(new Player(this,this.width/2/this.scale,0.5,0.05,"white",0.15,"me",this.root.settings.username,this.root.settings.photo));
this.mode = mode;
this.state = "waiting";
this.notice_board = new NoticeBoard(this);
this.score_board = new ScoreBoard(this);
this.player_count = 0;
if(mode === "single mode")
for (let i = 0; i < 5; i ++ ) {
this.players.push(new Player(this, this.width / 2/this.scale, 0.5, 0.05, this.get_random_color(), 0.15, "robot"));
} else if(mode === "multi mode"){
this.chat_field = new ChatField(this);
this.mps = new MultiPlayerSocket(this);
this.mps.uuid = this.players[0].uuid;
this.mps.ws.onopen = function(){
outer.mps.send_create_player(outer.root.settings.username,outer.root.settings.photo);
};
}
}
hide(){
while(this.players && this.players.length > 0){
this.players[0].destroy();
}
if(this.game_map){
this.game_map.destroy();
this.game_map = null;
}
if(this.notice_board){
this.notice_board.destroy();
this.notice_board = null;
}
if(this.score_board){
this.score_board.destroy();
this.score_board = null;
}
this.$playground.empty();
this.$playground.hide();
}
}

@ -0,0 +1,388 @@
class Settings{
constructor(root){
this.root = root;
this.platform = "WEB";
if(this.root.AcWingOS) this.platform = "ACAPP";
this.username = "";
this.photo = "https://cdn.acwing.com/media/user/profile/photo/355448_sm_2015d90652.jpg";
this.$settings = $(`
<div class="ac-game-settings">
<div class="ac-game-settings-login">
<div class="ac-game-settings-title">
登录
</div>
<div class="ac-game-settings-username">
<div class="ac-game-settings-item">
<input type="text" placeholder="用户名">
</div>
</div>
<div class="ac-game-settings-password">
<div class="ac-game-settings-item">
<input type="password" placeholder="密码">
</div>
</div>
<div class="ac-game-settings-submit">
<div class="ac-game-settings-item">
<button>登录</button>
</div>
</div>
<div class="ac-game-settings-error-message">
</div>
<br>
<br>
<div class="ac-game-settings-option">
注册
</div>
<br>
<div class="ac-game-settings-acwing">
<img width="30" src="https://app165.acapp.acwing.com.cn/static/image/settings/acwing_logo.png">
<br>
<br>
<div>
AcWing一键登录
</div>
</div>
</div>
<div class="ac-game-settings-register">
<div class="ac-game-settings-title">
注册
</div>
<div class="ac-game-settings-username">
<div class="ac-game-settings-item">
<input type="text" placeholder="用户名">
</div>
</div>
<div class="ac-game-settings-password ac-game-settings-password-first">
<div class="ac-game-settings-item">
<input type="password" placeholder="密码">
</div>
</div>
<div class="ac-game-settings-password ac-game-settings-password-second">
<div class="ac-game-settings-item">
<input type="password" placeholder="确认密码">
</div>
</div>
<div class="ac-game-settings-submit">
<div class="ac-game-settings-item">
<button>注册</button>
</div>
</div>
<div class="ac-game-settings-error-message">
</div>
<br>
<br>
<div class="ac-game-settings-option">
登录
</div>
<div class="ac-game-settings-acwing">
<img width="30" src="https://app165.acapp.acwing.com.cn/static/image/settings/acwing_logo.png">
<br>
<br>
<div>
AcWing一键登录
</div>
</div>
</div>
<div>
</div>
</div>
`);
this.$login = this.$settings.find(".ac-game-settings-login");
this.$login_username = this.$login.find(".ac-game-settings-username input");
this.$login_password = this.$login.find(".ac-game-settings-password input");
this.$login_submit = this.$login.find(".ac-game-settings-submit button");
this.$login_error_message = this.$login.find(".ac-game-settings-error-message");
this.$login_register = this.$login.find(".ac-game-settings-option");
this.$login.hide();
this.$register = this.$settings.find(".ac-game-settings-register");
this.$register_username = this.$register.find(".ac-game-settings-username input");
this.$register_password = this.$register.find(".ac-game-settings-password-first input");
this.$register_password_confirm = this.$register.find(".ac-game-settings-password-second input");
this.$register_submit = this.$register.find(".ac-game-settings-submit button");
this.$register_error_message = this.$register.find(".ac-game-settings-error-message");
this.$register_login = this.$register.find(".ac-game-settings-option");
this.$register.hide();
this.$acwing_login = this.$settings.find(".ac-game-settings-acwing img");
this.root.$ac_game.append(this.$settings);
this.start();
}
start(){
if (this.platform === "ACAPP"){
this.getinfo_acapp();
}else{
if(this.root.access){
this.getinfo_web();
this.refresh_jwt_token();
} else {
this.login();
}
this.add_listening_events();
}
}
refresh_jwt_token(){
setInterval(() => {
$.ajax({
url:"https://app6641.acapp.acwing.com.cn/settings/token/refresh/",
type:"post",
data:{
refresh:this.root.refresh,
},
success: resp => {
this.root.access = resp.access;
}
});
},4.5*60*1000);
setTimeout(() => {
$.ajax({
url:"https://app6641.acapp.acwing.com.cn/settings/ranklist/",
type:"GET",
headers:{
'Authorization': "Bearer "+ this.root.access,
},
success: resp => {
console.log(resp);
}
});
},5000);
}
add_listening_events(){
let outer = this;
this.add_listening_events_login();
this.add_listening_events_register();
this.$acwing_login.click(function(){
outer.acwing_login();
});
}
add_listening_events_login(){
let outer =this;
this.$login_register.click(function(){
outer.register();
});
this.$login_submit.click(function(){
outer.login_on_remote();
});
}
add_listening_events_register(){
let outer = this;
this.$register_login.click(function(){
outer.login();
});
this.$register_submit.click(function() {
outer.register_on_remote();
});
}
acwing_login() {
$.ajax({
url: "https://app6641.acapp.acwing.com.cn/settings/acwing/web/apply_code/",
type: "GET",
success: function(resp) {
if (resp.result === "success") {
window.location.replace(resp.apply_code_url);
}
}
});
}
login_on_remote(username , password) {
let outer = this;
username = username || this.$login_username.val();
password = password || this.$login_password.val();
this.$login_error_message.empty();
$.ajax({
url: "https://app6641.acapp.acwing.com.cn/settings/token/",
type: "post",
data: {
username: username,
password: password,
},
success: resp =>{
this.root.access = resp.access;
this.root.refresh = resp.refresh;
this.refresh_jwt_token();
this.getinfo_web();
},
error:() => {
this.$login_error_message.html("用户名密码错误");
},
});
}
register_on_remote(){
let outer = this;
let username = this.$register_username.val();
let password = this.$register_password.val();
let password_confirm = this.$register_password_confirm.val();
this.$register_error_message.empty();
$.ajax({
url: "https://app6641.acapp.acwing.com.cn/settings/register/",
type: "POST",
data: {
username: username,
password: password,
password_confirm:password_confirm,
},
success: resp =>{
if(resp.result === "success"){
this.login_on_remote(username,password);
} else {
this.$register_error_message.html(resp.result);
}
}
});
}
logout_on_remote(){
if(this.platform === "ACAPP") {
this.root.AcWingOS.api.window.close();
} else {
this.root.access = "";
this.root.refresh = "";
location.href = "/";
}
}
login(){//打开登陆界面
this.$register.hide();
this.$login.show();
}
register(){// 打开注册界面
this.$login.hide();
this.$register.show();
}
acapp_login(appid, redirect_uri, scope, state) {
let outer = this;
this.root.AcWingOS.api.oauth2.authorize(appid, redirect_uri, scope, state, function(resp) {
if (resp.result === "success") {
outer.username = resp.username;
outer.photo = resp.photo;
outer.hide();
outer.root.menu.show();
outer.root.access = resp.access;
outer.root.refresh = resp.refresh;
outer.refresh_jwt_token();
}
});
}
getinfo_acapp(){
let outer = this;
$.ajax({
url: "https://app6641.acapp.acwing.com.cn/settings/acwing/acapp/receive_code/",
type:"GET",
success: function(resp){
if(resp.result === "success"){
outer.acapp_login(resp.appid,resp.redirect_uri,resp.scope,resp.state);
}
}
});
}
getinfo_acapp() {
let outer = this;
$.ajax({
url: "https://app6641.acapp.acwing.com.cn/settings/acwing/acapp/apply_code/",
type: "GET",
success: function(resp) {
if (resp.result === "success") {
outer.acapp_login(resp.appid, resp.redirect_uri, resp.scope, resp.state);
}
}
});
}
getinfo_web(){
let outer = this;
$.ajax({
url:"https://app6641.acapp.acwing.com.cn/settings/getinfo/",
type:"get",
data:{
platform:outer.platform,
},
headers:{
'authorization':"Bearer "+this.root.access,
},
success:function(resp){
console.log(resp);
if(resp.result === "success"){
outer.username = resp.username;
outer.photo = resp.photo;
outer.hide();
outer.root.menu.show();
} else {
outer.login();
}
},
});
}
hide(){
this.$settings.hide();
}
show(){
this.$settings.show();
}
}

@ -0,0 +1,19 @@
export class AcGame {
constructor(id, AcWingOS, access, refresh) {
this.id = id;
this.$ac_game = $('#' + id);
this.AcWingOS = AcWingOS;
this.access = access;
this.refresh = refresh;
this.settings = new Settings(this);
this.menu = new AcGameMenu(this);
this.playground = new AcGamePlayground(this);
this.start();
}
start() {
}
}

@ -0,0 +1,158 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="https://cdn.acwing.com/media/article/image/2021/12/17/1_be4c11ce5f-acapp.png">
<title>头像选择</title>
<style>
body {
font-family: Arial, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
font-size: 24px;
background-image: url("/static/image/menu/123.gif");
}
.container {
text-align: center;
}
h1 {
font-size: 48px;
margin-bottom: 40px;
}
.avatar-container {
display: flex;
align-items: center;
justify-content: center;
margin: 40px 0;
}
.arrow {
font-size: 48px;
margin: 0 40px;
cursor: pointer;
color: aliceblue;
}
.avatar-placeholder {
width: 300px;
height: 300px;
border-radius: 50%;
border: 4px solid white;
display: flex;
align-items: center;
justify-content: center;
font-size: 28px;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.confirm-button {
padding: 20px 40px;
background-color: white;
color: black;
border: none;
cursor: pointer;
font-size: 28px;
margin-top: 40px;
border-radius: 20px;
}
</style>
</head>
<body>
<script>
document.addEventListener('DOMContentLoaded', () => {
const avatars = [
'/static/image/swgq.jpg',
'/static/image/lxq.jpg',
'/static/image/zyj.jpg'
];
let currentIndex = 0;
const avatarPlaceholder = document.querySelector('.avatar-placeholder');
const leftArrow = document.querySelector('.arrow:first-child');
const rightArrow = document.querySelector('.arrow:last-child');
const confirmButton = document.querySelector('.confirm-button');
const logoutButton = document.querySelector('.logout-button'); // 选择退出按钮
function updateAvatar() {
avatarPlaceholder.style.backgroundImage = `url('${avatars[currentIndex]}')`;
}
leftArrow.addEventListener('click', () => {
currentIndex = (currentIndex === 0) ? avatars.length - 1 : currentIndex - 1;
updateAvatar();
});
rightArrow.addEventListener('click', () => {
currentIndex = (currentIndex === avatars.length - 1) ? 0 : currentIndex + 1;
updateAvatar();
});
updateAvatar(); // 初始化显示第一个头像
// 用户信息对象
user = {
username: "{{ user.username|escapejs }}",
photo: "{{ user.player.photo|escapejs }}",
};
console.log("当前用户信息:", user);
// 绑定确认按钮的点击事件
confirmButton.addEventListener('click', () => {
user.photo = avatars[currentIndex];
console.log("更新头像为:", user.photo);
fetch('/update-avatar/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': '{{ csrf_token }}'
},
body: JSON.stringify({ photo: user.photo })
})
.then(response => {
if (response.ok) {
alert("头像已更新!");
} else {
alert("头像更新失败,请稍后重试。");
}
})
.catch(error => {
console.error("Error:", error);
alert("头像更新失败,请检查网络连接。");
});
});
// 绑定退出按钮的点击事件
logoutButton.addEventListener('click', () => {
window.location.href = 'https://app6641.acapp.acwing.com.cn/'; // 重定向到注销页面
});
});
</script>
<div class="container">
<h1>头像选择</h1>
<div class="avatar-container">
<div class="arrow">&#9664;</div>
<div class="avatar-placeholder"></div>
<div class="arrow">&#9654;</div>
</div>
<button class="confirm-button">确认</button>
<button class="logout-button">退出</button> <!-- 新增退出按钮 -->
</div>
</body>
</html>

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>用户资料</title>
</head>
<body>
<h1>用户资料</h1>
<p>用户名: {{ user.username }}</p>
<p>邮箱: {{ user.email }}</p>
<p>头像: <img src="{{ user.avatar.url }}" alt="用户头像" width="100"></p> <!-- 假设你的用户模型有头像字段 -->
<a href="{% url 'update_avatar' %}">更新头像</a>
</body>
</html>

@ -0,0 +1,19 @@
{% load static %}
<head>
<link rel="stylesheet" href="https://cdn.acwing.com/static/jquery-ui-dist/jquery-ui.min.css">
<script src="https://cdn.acwing.com/static/jquery/js/jquery-3.3.1.min.js"></script>
<link rel="stylesheet" href="{% static 'css/game.css' %}">
<link rel="icon" href="https://cdn.acwing.com/media/article/image/2021/12/17/1_be4c11ce5f-acapp.png">
</head>
<body style="margin: 0">
<div id="ac_game_12345678"></div>
<script type = "module">
import {AcGame} from "{% static 'js/dist/game.js' %}";
$(document).ready(function(){
let ac_game = new AcGame("ac_game_12345678",null,"{{ access }}","{{ refresh }}");
});
</script>
</body>

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

@ -0,0 +1,16 @@
from django.urls import path ,include
from game.views.index import index
from game.views.index import new_page,update_avatar
from game.views.settings.ranklist import RankListView
urlpatterns = [
path("",index,name="index"),
path("menu/",include("game.urls.menu.index")),
path("playground/",include("game.urls.playground.index")),
path("settings/",include("game.urls.settings.index")),
path("photo/",new_page),
path('update-avatar/', update_avatar, name='update_avatar'),
]

@ -0,0 +1,5 @@
from django.urls import path
urlpatterns = [
]

@ -0,0 +1,4 @@
from django.urls import path
urlpatterns = [
]

@ -0,0 +1,13 @@
from django.urls import path
from game.views.settings.acwing.web.apply_code import apply_code as web_apply_code
from game.views.settings.acwing.web.receive_code import receive_code as web_receive_code
from game.views.settings.acwing.acapp.apply_code import apply_code as acapp_apply_code
from game.views.settings.acwing.acapp.receive_code import receive_code as acapp_receive_code
urlpatterns = [
path("web/apply_code/",web_apply_code,name="settings_acwing_web_apply_code"),
path("web/receive_code/",web_receive_code,name="settings_acwing_web_receive_code"),
path("acapp/apply_code/",acapp_apply_code,name="settings_acwing_acapp_apply_code"),
path("acapp/receive_code/",acapp_receive_code,name="settings_acwing_acapp_receive_code"),
]

@ -0,0 +1,23 @@
from django.urls import path, include
from game.views.settings.getinfo import InfoView
from game.views.settings.register import PlayerView
from game.views.settings.ranklist import RankListView
from rest_framework_simplejwt.views import (
TokenObtainPairView,
TokenRefreshView,
)
urlpatterns = [
path('token/', TokenObtainPairView.as_view(), name='settings_token'),
path('token/refresh/', TokenRefreshView.as_view(), name='settings_token_refresh'),
path("getinfo/", InfoView.as_view(), name="settings_getinfo"),
path("register/", PlayerView.as_view(), name="settings_register"),
path("acwing/", include("game.urls.settings.acwing.index")),
path("ranklist/",RankListView.as_view(),name="settings_ranklsit"),
]

@ -0,0 +1,41 @@
from django.shortcuts import render
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
def index(request):
data = request.GET
context = {
'access':data.get('access',""),
'refresh':data.get('refresh',""),
}
return render(request,"multiends/web.html",context)
def new_page(request):
return render(request, 'menu/new.html', {'user': request.user})
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
import json
@login_required
@csrf_exempt
def update_avatar(request):
if request.method == 'POST':
data = json.loads(request.body)
new_photo = data.get('photo')
if new_photo:
# 更新用户的头像
player = request.user.player # 假设User模型和Player模型之间有OneToOne关系
player.photo = new_photo
player.save()
return JsonResponse({'status': 'success'})
else:
return JsonResponse({'status': 'error', 'message': 'No photo URL provided'}, status=400)
return JsonResponse({'status': 'error', 'message': 'Invalid request method'}, status=405)

@ -0,0 +1,29 @@
from django.http import JsonResponse
from urllib.parse import quote
from random import randint
from django.core.cache import cache
def get_state():
res = ""
for i in range(8):
res += str(randint(0, 9))
return res
def apply_code(request):
appid = "6641"
redirect_uri = quote("https://app6641.acapp.acwing.com.cn/settings/acwing/acapp/receive_code/")
scope = "userinfo"
state = get_state()
cache.set(state, True, 7200) # 有效期2小时
return JsonResponse({
'result': "success",
'appid':appid,
'redirect_uri': redirect_uri,
'scope':scope,
'state':state
})

@ -0,0 +1,78 @@
from django.http import JsonResponse
from django.core.cache import cache
import requests
from django.contrib.auth.models import User
from game.models.player.player import Player
from random import randint
from rest_framework_simplejwt.tokens import RefreshToken
def receive_code(request):
data = request.GET
if "errcode" in data:
return JsonResponse({
'result': "apply failed",
'errcode': data['errcode'],
'errmsg': data['errmsg'],
})
code = data.get('code')
state = data.get('state')
if not cache.has_key(state):
return JsonResponse({
'result': "state not exist"
})
cache.delete(state)
apply_access_token_url = "https://www.acwing.com/third_party/api/oauth2/access_token/"
params = {
'appid': "6641",
'secret': "aff89abe48f44aac93feab52df88b965",
'code': code
}
access_token_res = requests.get(apply_access_token_url, params=params).json()
access_token = access_token_res['access_token']
openid = access_token_res['openid']
players = Player.objects.filter(openid=openid)
if players.exists(): # 如果该用户已存在,则无需重新获取信息,直接登录即可
player = players[0]
refresh = RefreshToken.for_user(player.user)
return JsonResponse({
'result': "success",
'username': player.user.username,
'photo': player.photo,
'access':str(refresh.access_token),
'refresh':str(refresh),
})
get_userinfo_url = "https://www.acwing.com/third_party/api/meta/identity/getinfo/"
params = {
"access_token": access_token,
"openid": openid
}
userinfo_res = requests.get(get_userinfo_url, params=params).json()
username = userinfo_res['username']
photo = userinfo_res['photo']
while User.objects.filter(username=username).exists(): # 找到一个新用户名
username += str(randint(0, 9))
user = User.objects.create(username=username)
player = Player.objects.create(user=user, photo=photo, openid=openid)
refresh = RefreshToken.for_user(user)
return JsonResponse({
'result': "success",
'username': player.user.username,
'photo': player.photo,
'access':str(refresh.access_token),
'refresh':str(refresh),
})

@ -0,0 +1,27 @@
from django.http import JsonResponse
from urllib.parse import quote
from random import randint
from django.core.cache import cache
def get_state():
res = ""
for i in range(8):
res += str(randint(0, 9))
return res
def apply_code(request):
appid = "6641"
redirect_uri = quote("https://app6641.acapp.acwing.com.cn/settings/acwing/web/receive_code/")
scope = "userinfo"
state = get_state()
cache.set(state, True, 7200) # 有效期2小时
apply_code_url = "https://www.acwing.com/third_party/api/oauth2/web/authorize/"
return JsonResponse({
'result': "success",
'apply_code_url': apply_code_url + "?appid=%s&redirect_uri=%s&scope=%s&state=%s" % (appid, redirect_uri, scope, state)
})

@ -0,0 +1,48 @@
from django.shortcuts import redirect,reverse
from django.core.cache import cache
import requests
from django.contrib.auth.models import User
from game.models.player.player import Player
from random import randint
from rest_framework_simplejwt.tokens import RefreshToken
def receive_code(request):
data = request.GET
code = data.get('code')
state = data.get('state')
if not cache.has_key(state):
return redirect("index")
cache.delete(state)
apply_access_token_url = "https://www.acwing.com/third_party/api/oauth2/access_token/"
params = {
'appid': "6641",
'secret': "aff89abe48f44aac93feab52df88b965",
'code' : code
}
access_token_res = requests.get(apply_access_token_url, params=params).json()
access_token = access_token_res['access_token']
openid = access_token_res['openid']
players = Player.objects.filter(openid = openid)
if players.exists():
refresh = RefreshToken.for_user(players[0].user)
return redirect(reverse("index") + "?access=%s&refresh=%s" % (str(refresh.access_token),str(refresh)))
get_userinfo_url = "https://www.acwing.com/third_party/api/meta/identity/getinfo/"
params = {
'access_token': access_token,
'openid': openid
}
userinfo_res = requests.get(get_userinfo_url,params=params).json()
username = userinfo_res['username']
photo = userinfo_res['photo']
while User.objects.filter(username = username).exists():
username += str(randint(0,9))
user = User.objects.create(username=username)
player = Player.objects.create(user=user,photo=photo,openid=openid)
refresh = RefreshToken.for_user(user)
return redirect(reverse("index") + "?access=%s&refresh=%s" % (str(refresh.access_token), str(refresh)))

@ -0,0 +1,22 @@
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from game.models.player.player import Player
class InfoView(APIView):
permission_classes = ([IsAuthenticated])
def get(self,request):
user = request.user
player = Player.objects.get(user=user)
return Response({
'result':"success",
'username':user.username,
'photo':player.photo,
})

@ -0,0 +1,23 @@
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from game.models.player.player import Player
class RankListView(APIView):
permission_classes = ([IsAuthenticated])
def get(self,request):
players = Player.objects.all().order_by('-score')[:8]
resp = []
for player in players:
resp.append({
'username': player.user.username,
'photo':player.photo,
'score':player.score,
})
return Response(resp)

@ -0,0 +1,35 @@
from rest_framework.views import APIView
from rest_framework.response import Response
from django.contrib.auth.models import User
from game.models.player.player import Player
class PlayerView(APIView):
def post(self,request):
data = request.POST
username = data.get("username", "").strip()
password = data.get("password", "").strip()
password_confirm = data.get("password_confirm", "").strip()
print(username)
if not username or not password:
return Response({
'result':request.GET.get("username")
})
if password != password_confirm:
return Response({
'result': "两个密码不一致",
})
if User.objects.filter(username=username).exists():
return Response({
'result': "用户名已存在"
})
user = User(username=username)
user.set_password(password)
user.save()
Player.objects.create(user=user, photo="https://cdn.acwing.com/media/user/profile/photo/355448_sm_2015d90652.jpg")
return Response({
'result': "success",
})

@ -0,0 +1,22 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'acapp.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()

@ -0,0 +1,141 @@
#! /usr/bin/env python3
import glob
import sys
sys.path.insert(0, glob.glob('../../')[0])
from match_server.match_service import Match
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer
from queue import Queue
from time import sleep
from threading import Thread
from acapp.asgi import channel_layer
from asgiref.sync import async_to_sync
from django.core.cache import cache
queue = Queue() # 消息队列
class Player:
def __init__(self, score, uuid, username, photo, channel_name):
self.score = score
self.uuid = uuid
self.username = username
self.photo = photo
self.channel_name = channel_name
self.waiting_time = 0 # 等待时间
class Pool:
def __init__(self):
self.players = []
def add_player(self, player):
self.players.append(player)
def check_match(self, a, b):
dt = abs(a.score - b.score)
a_max_dif = a.waiting_time * 50
b_max_dif = b.waiting_time * 50
return dt <= a_max_dif and dt <= b_max_dif
def match_success(self, ps):
print("Match Success: %s %s %s" % (ps[0].username, ps[1].username, ps[2].username))
room_name = "room-%s-%s-%s" % (ps[0].uuid, ps[1].uuid, ps[2].uuid)
players = []
for p in ps:
async_to_sync(channel_layer.group_add)(room_name, p.channel_name)
players.append({
'uuid': p.uuid,
'username': p.username,
'photo': p.photo,
'hp': 100,
})
cache.set(room_name, players, 3600) # 有效时间1小时
for p in ps:
async_to_sync(channel_layer.group_send)(
room_name,
{
'type': "group_send_event",
'event': "create_player",
'uuid': p.uuid,
'username': p.username,
'photo': p.photo,
}
)
def increase_waiting_time(self):
for player in self.players:
player.waiting_time += 1
def match(self):
while len(self.players) >= 3:
self.players = sorted(self.players, key=lambda p: p.score)
flag = False
for i in range(len(self.players) - 2):
a, b, c = self.players[i], self.players[i + 1], self.players[i + 2]
if self.check_match(a, b) and self.check_match(a, c) and self.check_match(b, c):
self.match_success([a, b, c])
self.players = self.players[:i] + self.players[i + 3:]
flag = True
break
if not flag:
break
self.increase_waiting_time()
class MatchHandler:
def add_player(self, score, uuid, username, photo, channel_name):
print("Add Player: %s %d" % (username, score))
player = Player(score, uuid, username, photo, channel_name)
queue.put(player)
return 0
def get_player_from_queue():
try:
return queue.get_nowait()
except:
return None
def worker():
pool = Pool()
while True:
player = get_player_from_queue()
if player:
pool.add_player(player)
else:
pool.match()
sleep(1)
if __name__ == '__main__':
handler = MatchHandler()
processor = Match.Processor(handler)
transport = TSocket.TServerSocket(host='127.0.0.1', port=9090)
tfactory = TTransport.TBufferedTransportFactory()
pfactory = TBinaryProtocol.TBinaryProtocolFactory()
server = TServer.TThreadedServer(
processor, transport, tfactory, pfactory)
Thread(target=worker, daemon=True).start()
print('Starting the server...')
server.serve()
print('done.')

@ -0,0 +1,117 @@
#!/usr/bin/env python
#
# Autogenerated by Thrift Compiler (0.16.0)
#
# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
#
# options string: py
#
import sys
import pprint
if sys.version_info[0] > 2:
from urllib.parse import urlparse
else:
from urlparse import urlparse
from thrift.transport import TTransport, TSocket, TSSLSocket, THttpClient
from thrift.protocol.TBinaryProtocol import TBinaryProtocol
from match_service import Match
from match_service.ttypes import *
if len(sys.argv) <= 1 or sys.argv[1] == '--help':
print('')
print('Usage: ' + sys.argv[0] + ' [-h host[:port]] [-u url] [-f[ramed]] [-s[sl]] [-novalidate] [-ca_certs certs] [-keyfile keyfile] [-certfile certfile] function [arg1 [arg2...]]')
print('')
print('Functions:')
print(' i32 add_player(i32 score, string uuid, string username, string photo, string channel_name)')
print('')
sys.exit(0)
pp = pprint.PrettyPrinter(indent=2)
host = 'localhost'
port = 9090
uri = ''
framed = False
ssl = False
validate = True
ca_certs = None
keyfile = None
certfile = None
http = False
argi = 1
if sys.argv[argi] == '-h':
parts = sys.argv[argi + 1].split(':')
host = parts[0]
if len(parts) > 1:
port = int(parts[1])
argi += 2
if sys.argv[argi] == '-u':
url = urlparse(sys.argv[argi + 1])
parts = url[1].split(':')
host = parts[0]
if len(parts) > 1:
port = int(parts[1])
else:
port = 80
uri = url[2]
if url[4]:
uri += '?%s' % url[4]
http = True
argi += 2
if sys.argv[argi] == '-f' or sys.argv[argi] == '-framed':
framed = True
argi += 1
if sys.argv[argi] == '-s' or sys.argv[argi] == '-ssl':
ssl = True
argi += 1
if sys.argv[argi] == '-novalidate':
validate = False
argi += 1
if sys.argv[argi] == '-ca_certs':
ca_certs = sys.argv[argi+1]
argi += 2
if sys.argv[argi] == '-keyfile':
keyfile = sys.argv[argi+1]
argi += 2
if sys.argv[argi] == '-certfile':
certfile = sys.argv[argi+1]
argi += 2
cmd = sys.argv[argi]
args = sys.argv[argi + 1:]
if http:
transport = THttpClient.THttpClient(host, port, uri)
else:
if ssl:
socket = TSSLSocket.TSSLSocket(host, port, validate=validate, ca_certs=ca_certs, keyfile=keyfile, certfile=certfile)
else:
socket = TSocket.TSocket(host, port)
if framed:
transport = TTransport.TFramedTransport(socket)
else:
transport = TTransport.TBufferedTransport(socket)
protocol = TBinaryProtocol(transport)
client = Match.Client(protocol)
transport.open()
if cmd == 'add_player':
if len(args) != 5:
print('add_player requires 5 args')
sys.exit(1)
pp.pprint(client.add_player(eval(args[0]), args[1], args[2], args[3], args[4],))
else:
print('Unrecognized method %s' % cmd)
sys.exit(1)
transport.close()

@ -0,0 +1,306 @@
#
# Autogenerated by Thrift Compiler (0.16.0)
#
# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
#
# options string: py
#
from thrift.Thrift import TType, TMessageType, TFrozenDict, TException, TApplicationException
from thrift.protocol.TProtocol import TProtocolException
from thrift.TRecursive import fix_spec
import sys
import logging
from .ttypes import *
from thrift.Thrift import TProcessor
from thrift.transport import TTransport
all_structs = []
class Iface(object):
def add_player(self, score, uuid, username, photo, channel_name):
"""
Parameters:
- score
- uuid
- username
- photo
- channel_name
"""
pass
class Client(Iface):
def __init__(self, iprot, oprot=None):
self._iprot = self._oprot = iprot
if oprot is not None:
self._oprot = oprot
self._seqid = 0
def add_player(self, score, uuid, username, photo, channel_name):
"""
Parameters:
- score
- uuid
- username
- photo
- channel_name
"""
self.send_add_player(score, uuid, username, photo, channel_name)
return self.recv_add_player()
def send_add_player(self, score, uuid, username, photo, channel_name):
self._oprot.writeMessageBegin('add_player', TMessageType.CALL, self._seqid)
args = add_player_args()
args.score = score
args.uuid = uuid
args.username = username
args.photo = photo
args.channel_name = channel_name
args.write(self._oprot)
self._oprot.writeMessageEnd()
self._oprot.trans.flush()
def recv_add_player(self):
iprot = self._iprot
(fname, mtype, rseqid) = iprot.readMessageBegin()
if mtype == TMessageType.EXCEPTION:
x = TApplicationException()
x.read(iprot)
iprot.readMessageEnd()
raise x
result = add_player_result()
result.read(iprot)
iprot.readMessageEnd()
if result.success is not None:
return result.success
raise TApplicationException(TApplicationException.MISSING_RESULT, "add_player failed: unknown result")
class Processor(Iface, TProcessor):
def __init__(self, handler):
self._handler = handler
self._processMap = {}
self._processMap["add_player"] = Processor.process_add_player
self._on_message_begin = None
def on_message_begin(self, func):
self._on_message_begin = func
def process(self, iprot, oprot):
(name, type, seqid) = iprot.readMessageBegin()
if self._on_message_begin:
self._on_message_begin(name, type, seqid)
if name not in self._processMap:
iprot.skip(TType.STRUCT)
iprot.readMessageEnd()
x = TApplicationException(TApplicationException.UNKNOWN_METHOD, 'Unknown function %s' % (name))
oprot.writeMessageBegin(name, TMessageType.EXCEPTION, seqid)
x.write(oprot)
oprot.writeMessageEnd()
oprot.trans.flush()
return
else:
self._processMap[name](self, seqid, iprot, oprot)
return True
def process_add_player(self, seqid, iprot, oprot):
args = add_player_args()
args.read(iprot)
iprot.readMessageEnd()
result = add_player_result()
try:
result.success = self._handler.add_player(args.score, args.uuid, args.username, args.photo, args.channel_name)
msg_type = TMessageType.REPLY
except TTransport.TTransportException:
raise
except TApplicationException as ex:
logging.exception('TApplication exception in handler')
msg_type = TMessageType.EXCEPTION
result = ex
except Exception:
logging.exception('Unexpected exception in handler')
msg_type = TMessageType.EXCEPTION
result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
oprot.writeMessageBegin("add_player", msg_type, seqid)
result.write(oprot)
oprot.writeMessageEnd()
oprot.trans.flush()
# HELPER FUNCTIONS AND STRUCTURES
class add_player_args(object):
"""
Attributes:
- score
- uuid
- username
- photo
- channel_name
"""
def __init__(self, score=None, uuid=None, username=None, photo=None, channel_name=None,):
self.score = score
self.uuid = uuid
self.username = username
self.photo = photo
self.channel_name = channel_name
def read(self, iprot):
if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
return
iprot.readStructBegin()
while True:
(fname, ftype, fid) = iprot.readFieldBegin()
if ftype == TType.STOP:
break
if fid == 1:
if ftype == TType.I32:
self.score = iprot.readI32()
else:
iprot.skip(ftype)
elif fid == 2:
if ftype == TType.STRING:
self.uuid = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
else:
iprot.skip(ftype)
elif fid == 3:
if ftype == TType.STRING:
self.username = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
else:
iprot.skip(ftype)
elif fid == 4:
if ftype == TType.STRING:
self.photo = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
else:
iprot.skip(ftype)
elif fid == 5:
if ftype == TType.STRING:
self.channel_name = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
else:
iprot.skip(ftype)
else:
iprot.skip(ftype)
iprot.readFieldEnd()
iprot.readStructEnd()
def write(self, oprot):
if oprot._fast_encode is not None and self.thrift_spec is not None:
oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
return
oprot.writeStructBegin('add_player_args')
if self.score is not None:
oprot.writeFieldBegin('score', TType.I32, 1)
oprot.writeI32(self.score)
oprot.writeFieldEnd()
if self.uuid is not None:
oprot.writeFieldBegin('uuid', TType.STRING, 2)
oprot.writeString(self.uuid.encode('utf-8') if sys.version_info[0] == 2 else self.uuid)
oprot.writeFieldEnd()
if self.username is not None:
oprot.writeFieldBegin('username', TType.STRING, 3)
oprot.writeString(self.username.encode('utf-8') if sys.version_info[0] == 2 else self.username)
oprot.writeFieldEnd()
if self.photo is not None:
oprot.writeFieldBegin('photo', TType.STRING, 4)
oprot.writeString(self.photo.encode('utf-8') if sys.version_info[0] == 2 else self.photo)
oprot.writeFieldEnd()
if self.channel_name is not None:
oprot.writeFieldBegin('channel_name', TType.STRING, 5)
oprot.writeString(self.channel_name.encode('utf-8') if sys.version_info[0] == 2 else self.channel_name)
oprot.writeFieldEnd()
oprot.writeFieldStop()
oprot.writeStructEnd()
def validate(self):
return
def __repr__(self):
L = ['%s=%r' % (key, value)
for key, value in self.__dict__.items()]
return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
def __eq__(self, other):
return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
def __ne__(self, other):
return not (self == other)
all_structs.append(add_player_args)
add_player_args.thrift_spec = (
None, # 0
(1, TType.I32, 'score', None, None, ), # 1
(2, TType.STRING, 'uuid', 'UTF8', None, ), # 2
(3, TType.STRING, 'username', 'UTF8', None, ), # 3
(4, TType.STRING, 'photo', 'UTF8', None, ), # 4
(5, TType.STRING, 'channel_name', 'UTF8', None, ), # 5
)
class add_player_result(object):
"""
Attributes:
- success
"""
def __init__(self, success=None,):
self.success = success
def read(self, iprot):
if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
return
iprot.readStructBegin()
while True:
(fname, ftype, fid) = iprot.readFieldBegin()
if ftype == TType.STOP:
break
if fid == 0:
if ftype == TType.I32:
self.success = iprot.readI32()
else:
iprot.skip(ftype)
else:
iprot.skip(ftype)
iprot.readFieldEnd()
iprot.readStructEnd()
def write(self, oprot):
if oprot._fast_encode is not None and self.thrift_spec is not None:
oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
return
oprot.writeStructBegin('add_player_result')
if self.success is not None:
oprot.writeFieldBegin('success', TType.I32, 0)
oprot.writeI32(self.success)
oprot.writeFieldEnd()
oprot.writeFieldStop()
oprot.writeStructEnd()
def validate(self):
return
def __repr__(self):
L = ['%s=%r' % (key, value)
for key, value in self.__dict__.items()]
return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
def __eq__(self, other):
return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
def __ne__(self, other):
return not (self == other)
all_structs.append(add_player_result)
add_player_result.thrift_spec = (
(0, TType.I32, 'success', None, None, ), # 0
)
fix_spec(all_structs)
del all_structs

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save