Initial commit

master
root 2022-11-18 08:04:33 +00:00
commit e13de02143
335 changed files with 70525 additions and 0 deletions

4
.dockerignore Executable file
View File

@ -0,0 +1,4 @@
unity/game
!unity/game/Builds
# unity/game/Logs
# unity/game/UserSettings

1
.gitignore vendored Executable file
View File

@ -0,0 +1 @@
/saved/

66
Dockerfile Executable file
View File

@ -0,0 +1,66 @@
# FROM unityci/editor:ubuntu-2022.1.22f1-webgl-1.0.1 AS dungeonsandexploits_builder
# COPY "unity/game" "game"
# # RUN "$UNITY_PATH/Editor/Unity" \
# # -quit -batchmode -nographics \
# # -logFile "/dev/stdout" \
# # -createManualActivationFile \
# # -username "swzlcclbftnhqnzbgr@tmmcv.net" -password "D7H6L5dJ8nHXSRJ" -returnlicense
# # RUN cat "/Unity_v2022.1.22f1.alf"
# # https://license.unity3d.com/manual
# COPY "unity/Unity_v2022.x.ulf" "/root/.local/share/unity3d/Unity/Unity_lic.ulf"
# # RUN unity-editor \
# RUN "$UNITY_PATH/Editor/Unity" \
# -quit -batchmode -nographics \
# -logFile "/dev/stdout" \
# -projectPath "./game/" \
# -executeMethod "WebGLBuilder.Build"
FROM debian:latest AS dungeonsandexploits
# USERS
# RUN addgroup --system appgroup && adduser --ingroup appgroup --system appuser
WORKDIR /tmp
RUN apt-get update
# flask
RUN mkdir -p "/root/flask" && chmod -R "o=rX" "/root"
WORKDIR /root/flask
# # install dependencies
RUN apt-get install --no-install-recommends --upgrade -y python3 python3-pip
# init flask dependencies
COPY "flask/requirements.txt" "requirements.txt"
RUN chmod -R "o=rX" "/root"
# USER appuser
RUN python3 -m pip install --no-cache-dir --upgrade -r "requirements.txt"
# USER root
# clean some dependencies after build
RUN apt-get purge -y python3-pip
# init flask
COPY "flask/auth.py" "flask/game.py" "flask/server.py" "flask/website.py" ./
COPY "flask/models" "./models"
COPY "flask/static" "./static"
COPY "unity/game/Builds/WebGL" "./static/game"
# COPY --from="dungeonsandexploits_builder" "game/Builds/WebGL" "./static/game"
COPY "flask/templates" "./templates"
RUN chmod -R "o=rX" "/root"
# init https
# COPY "flask/cert.pem" "flask/key.pem" ./
# RUN chmod "444" "cert.pem" "key.pem"
# CLEANUP APT CACHE
RUN apt-get clean && rm -r /var/lib/apt/lists/*
# RUN
# USER appuser:appgroup
WORKDIR /root/flask
EXPOSE 8000
# ENTRYPOINT [ "/home/appuser/.local/bin/gunicorn", "server:app", \
ENTRYPOINT [ "/usr/local/bin/gunicorn", "server:app", \
"--bind", "0.0.0.0:8000", \
"--workers", "1", \
"--threads", "16", \
"--keyfile", "/secrets/privkey.pem", \
"--certfile", "/secrets/fullchain.pem" \
]

13
docker-compose.yml Executable file
View File

@ -0,0 +1,13 @@
version: "3.8"
services:
dungeonsandexploits:
container_name: dungeonsandexploits
hostname: dungeonsandexploits
image: dungeonsandexploits
build: .
ports:
- 4242:8000
volumes:
- /secrets/dungeonsandexploits:/secrets
restart: unless-stopped
# environment:

1
flask/.dockerignore Executable file
View File

@ -0,0 +1 @@
venv*

403
flask/.eslintrc Executable file
View File

@ -0,0 +1,403 @@
extends:
- "eslint:recommended"
# - "plugin:node/recommended"
# - "plugin:jsdoc/recommended"
# - "plugin:eslint-comments/recommended"
reportUnusedDisableDirectives: true
parserOptions:
ecmaVersion: 12
sourceType: module
ecmaFeatures:
jsx: true
env:
browser: true
rules:
array-bracket-spacing: error
array-callback-return: error
arrow-body-style:
- error
- as-needed
arrow-parens:
- error
- as-needed
arrow-spacing: error
block-spacing: error
brace-style:
- error
- 1tbs
camelcase: error
class-methods-use-this: error
comma-dangle: error
comma-spacing: error
comma-style:
- error
- last
computed-property-spacing: error
consistent-return: error
curly:
- error
- all
default-case: error
default-case-last: error
default-param-last: error
dot-location:
- error
- property
dot-notation:
- error
-
allowKeywords: true
eol-last: error
eqeqeq: error
# eslint-comments/disable-enable-pair:
# - error
# eslint-comments/no-unused-disable: error
# eslint-comments/require-description: error
func-call-spacing: error
func-style:
- error
- declaration
function-call-argument-newline:
- error
- consistent
function-paren-newline:
- error
- consistent
generator-star-spacing: error
grouped-accessor-pairs: error
guard-for-in: error
indent:
- error
- 4
-
SwitchCase: 1
# jsdoc/check-access: error
# jsdoc/check-alignment: error
# jsdoc/check-line-alignment:
# - error
# - never
# jsdoc/check-param-names: error
# jsdoc/check-property-names: error
# jsdoc/check-syntax: error
# jsdoc/check-tag-names: error
# jsdoc/check-types: error
# jsdoc/check-values:
# - error
# -
# allowedLicenses: true
# jsdoc/empty-tags: error
# jsdoc/implements-on-classes: error
# jsdoc/multiline-blocks: error
# jsdoc/newline-after-description:
# - error
# - never
# jsdoc/no-bad-blocks: error
# jsdoc/no-multi-asterisks: error
# jsdoc/no-undefined-types: "off"
# jsdoc/require-asterisk-prefix: error
# jsdoc/require-description:
# - error
# -
# checkConstructors: false
# jsdoc/require-hyphen-before-param-description:
# - error
# - never
# jsdoc/require-jsdoc:
# - error
# -
# require:
# ClassDeclaration: true
# jsdoc/require-param: error
# jsdoc/require-param-description: error
# jsdoc/require-param-name: error
# jsdoc/require-param-type: error
# jsdoc/require-property: error
# jsdoc/require-property-description: error
# jsdoc/require-property-name: error
# jsdoc/require-property-type: error
# jsdoc/require-returns:
# - error
# -
# forceRequireReturn: true
# forceReturnsWithAsync: true
# jsdoc/require-returns-check: error
# jsdoc/require-returns-description: error
# jsdoc/require-returns-type: error
# jsdoc/require-throws: error
# jsdoc/require-yields: "off"
# jsdoc/require-yields-check: error
# jsdoc/tag-lines:
# - error
# - never
# -
# tags:
# example:
# lines: always
# fileoverview:
# lines: any
# jsdoc/valid-types: error
key-spacing:
- error
-
afterColon: true
beforeColon: false
keyword-spacing: error
lines-around-comment:
- error
-
afterBlockComment: false
afterLineComment: false
beforeBlockComment: true
beforeLineComment: true
max-len:
- error
- 160
-
ignoreComments: true
ignoreRegExpLiterals: true
ignoreStrings: true
ignoreTemplateLiterals: true
ignoreUrls: true
max-statements-per-line: error
new-cap: error
new-parens: error
no-alert: error
no-array-constructor: error
no-caller: error
no-confusing-arrow: error
no-console: error
no-constructor-return: error
no-else-return:
- error
-
allowElseIf: false
no-eval: error
no-extend-native: error
no-extra-bind: error
no-floating-decimal: error
no-implied-eval: error
no-invalid-this: error
no-iterator: error
no-label-var: error
no-labels: error
no-lone-blocks: error
no-loop-func: error
no-mixed-spaces-and-tabs:
- error
- false
no-multi-spaces: error
no-multi-str: error
no-multiple-empty-lines:
- error
-
max: 2
maxBOF: 0
maxEOF: 0
no-nested-ternary: error
no-new: error
no-new-func: error
no-new-object: error
no-new-wrappers: error
no-octal-escape: error
no-param-reassign: error
no-process-exit: "off"
no-proto: error
no-restricted-properties:
- error
-
message: "Use .slice instead of .substring."
property: substring
-
message: "Use .slice instead of .substr."
property: substr
-
message: "Use assert.strictEqual instead of assert.equal."
object: assert
property: equal
-
message: "Use assert.notStrictEqual instead of assert.notEqual."
object: assert
property: notEqual
-
message: "Use assert.deepStrictEqual instead of assert.deepEqual."
object: assert
property: deepEqual
-
message: "Use assert.notDeepStrictEqual instead of assert.notDeepEqual."
object: assert
property: notDeepEqual
no-return-assign: error
no-script-url: error
no-self-compare: error
no-sequences: error
no-shadow: error
no-tabs: error
no-throw-literal: error
no-trailing-spaces: error
no-undef:
- error
-
typeof: true
no-undef-init: error
no-undefined: error
no-underscore-dangle:
- error
-
allowAfterThis: true
no-unmodified-loop-condition: error
no-unneeded-ternary: error
no-unreachable-loop: error
no-unused-expressions: error
no-unused-vars:
- error
-
args: after-used
caughtErrors: all
vars: all
no-use-before-define: error
no-useless-call: error
no-useless-computed-key: error
no-useless-concat: error
no-useless-constructor: error
no-useless-rename: error
no-useless-return: error
no-var: error
no-whitespace-before-property: error
# node/callback-return:
# - error
# -
# - cb
# - callback
# - next
# node/handle-callback-err:
# - error
# - err
# node/no-deprecated-api: error
# node/no-mixed-requires: error
# node/no-new-require: error
# node/no-path-concat: error
object-curly-newline:
- error
-
consistent: true
multiline: true
object-curly-spacing:
- error
- always
object-property-newline:
- error
-
allowAllPropertiesOnSameLine: true
object-shorthand: error
one-var-declaration-per-line: error
operator-assignment: error
operator-linebreak: error
padding-line-between-statements:
- error
-
blankLine: always
next: "*"
prev:
- const
- let
- var
-
blankLine: any
next:
- const
- let
- var
prev:
- const
- let
- var
prefer-arrow-callback: error
prefer-const: error
prefer-exponentiation-operator: error
prefer-numeric-literals: error
prefer-promise-reject-errors: error
prefer-regex-literals: error
prefer-rest-params: error
prefer-spread: error
prefer-template: error
quote-props:
- error
- as-needed
quotes:
- error
- double
-
avoidEscape: true
radix: error
require-unicode-regexp: error
rest-spread-spacing: error
semi: error
semi-spacing:
- error
-
after: true
before: false
semi-style: error
space-before-blocks: error
space-before-function-paren:
- error
-
anonymous: never
asyncArrow: always
named: never
space-in-parens: error
space-infix-ops: error
space-unary-ops:
- error
-
nonwords: false
words: true
spaced-comment:
- error
- always
-
exceptions:
- "-"
strict:
- error
- global
switch-colon-spacing: error
symbol-description: error
template-curly-spacing:
- error
- never
template-tag-spacing: error
unicode-bom: error
wrap-iife: error
yield-star-spacing: error
yoda:
- error
- never
-
exceptRange: true
settings:
jsdoc:
preferredTypes:
? "*"
:
message: "Use a more precise type or if necessary use `any` or `ArbitraryCallbackResult`"
replacement: any
.<>:
message: "Prefer type form without dot"
replacement: <>
Any:
message: "Use a more precise type or if necessary use `any` or `ArbitraryCallbackResult`"
replacement: any
Promise:
message: "Specify the specific Promise type, including, if necessary, the type `any`"
array: Array
function:
message: "Point to a `@callback` namepath or `Function` if truly arbitrary in form"
replacement: Function
object:
message: "Use the specific object type or `Object` if truly arbitrary"
replacement: Object
tagNamePreference:
augments: extends
class: constructor
file: fileoverview

6
flask/.gitignore vendored Executable file
View File

@ -0,0 +1,6 @@
__pycache__/
*.db
*.log
*.pem
venv*/
worlds.json

3
flask/.jshintrc Executable file
View File

@ -0,0 +1,3 @@
{
"esversion": 9
}

140
flask/auth.py Executable file
View File

@ -0,0 +1,140 @@
from flask import Blueprint, jsonify, request
from flask_login import login_required, login_user, logout_user
from flask_wtf import FlaskForm
from flask_wtf.csrf import generate_csrf
from models import User
from server import db, login_manager
from sqlalchemy.orm import Session
from werkzeug.datastructures import ImmutableMultiDict
from wtforms import (BooleanField, PasswordField, StringField, SubmitField,
validators)
auth = Blueprint("auth", __name__,)
db_session = Session(db, future=True)
@login_manager.user_loader
def load_user(user_id):
return User.query.get(user_id)
@auth.route("/csrf", methods=["GET"])
def csrf():
return jsonify({"csrfToken": generate_csrf()}), 200
def str_form_errors(form_errors):
str_errors = []
for k, errors in form_errors.items():
if k is None:
k = "Error"
for error in errors:
str_errors.append(f"{k}: {error}")
return ", ".join(str_errors)
class LoginForm(FlaskForm):
username = StringField(
label="Username",
validators=[
validators.InputRequired(),
],
id="username",
default="user",
name="username",
)
password = PasswordField(
label="Password",
validators=[
validators.InputRequired(),
],
id="password",
default="password",
name="password",
)
remember_me = BooleanField(
"Remember me",
)
_fail_message = "wrong credentials"
def validate(self, extra_validators=None):
if not super().validate(extra_validators=extra_validators):
return False
self._user = User.query.filter(User.username == self.username.data).first()
if self._user is None:
self.form_errors.append(self._fail_message)
return False
if not self._user.verify(self.password.data):
self.form_errors.append(self._fail_message)
return False
return True
@auth.route("/login", methods=["GET", "POST"])
def login():
form = LoginForm(ImmutableMultiDict(request.get_json()))
if form.validate_on_submit():
login_user(form._user, remember=form.remember_me.data)
return jsonify({"ok": True}), 200
return jsonify({"ok": False, "errors": str_form_errors(form.errors)}), 400
login_manager.login_view = "auth.login"
def username_does_not_exist_validator(form, field):
if User.exists(username=field.data):
raise validators.ValidationError("username already exists")
return True
class RegisterForm(FlaskForm):
username = StringField(
"Username",
validators=[
validators.DataRequired(),
validators.Length(min=3),
username_does_not_exist_validator,
]
)
password = PasswordField(
"Password",
validators=[
validators.DataRequired(),
validators.Length(min=8),
]
)
confirm = PasswordField(
"Repeat password",
validators=[
validators.DataRequired(),
validators.EqualTo("password", message="passwords do not match"),
]
)
@auth.route("/register", methods=["GET", "POST"])
def register():
form = RegisterForm(ImmutableMultiDict(request.get_json()))
if form.validate_on_submit():
User.register(
username=form.username.data,
password=form.password.data,
)
return jsonify({"ok": True}), 200
return jsonify({"ok": False, "errors": str_form_errors(form.errors)}), 400
@auth.route("/logout", methods=["GET", "POST"])
@login_required
def logout():
logout_user()
return jsonify({"ok": True}), 200
# @login_manager.unauthorized_handler
# def unauthorized():
# return abort(401)

9
flask/clear.sh Executable file
View File

@ -0,0 +1,9 @@
#!/bin/bash
set -e
here="$(realpath "$(dirname "$0")")"
cd "$here"
sudo rm -rf \
./*.log \
./*.pem \
./venv*

9
flask/dep_run.sh Executable file
View File

@ -0,0 +1,9 @@
#!/bin/sh
set -e
cd "$(dirname "$0")"
. "./venv/bin/activate"
# export FLASK_APP="server:app"
# flask db init || :
# flask db migrate -m "$(date)"
# flask db upgrade
gunicorn "server:app" --bind "127.0.0.1:8000" --workers 1 --threads 16 --keyfile "key.pem" --certfile "cert.pem" --reload

17
flask/dev_init.sh Executable file
View File

@ -0,0 +1,17 @@
#!/bin/bash
set -e
here="$(realpath "$(dirname "$0")")"
cd "$here"
echo "---------- install and upgrade pip ----------"
python -m pip install --upgrade pip
echo "---------- initialize venv ----------"
python3 -m venv venv
source "./venv/bin/activate"
echo "---------- install dependencies ----------"
python -m pip install --upgrade -r "requirements.txt"
echo "---------- run init.sh ----------"
"./init.sh"
cd "$here"
echo "---------- done ----------"

11
flask/dev_run.sh Executable file
View File

@ -0,0 +1,11 @@
#!/bin/sh
set -e
cd "$(dirname "$0")"
. "./venv/bin/activate"
export FLASK_DEBUG="1"
export FLASK_APP="server:app"
export FLASK_RUN_PORT="8000"
# flask db init || :
# flask db migrate -m "$(date)"
# flask db upgrade
python3 -m flask run --port "$FLASK_RUN_PORT" 2>&1 | tee -a "./server.log"

247
flask/game.py Executable file
View File

@ -0,0 +1,247 @@
import base64
import json
import traceback
import zlib
import simple_websocket
from flask import Blueprint, request
from flask_login import current_user, login_required
from models import User
from server import db
from sqlalchemy.orm.attributes import flag_modified
game = Blueprint("game", __name__)
ok_msg = json.dumps({"ok": True})
unparsable_msg = "huh?"
fail_msg = json.dumps({"ok": False})
def serialize(data):
return base64.standard_b64encode(zlib.compress(data.encode("ascii"), level=-1)).decode("ascii")
def unserialize(data):
return zlib.decompress(base64.standard_b64decode(data.encode("ascii"))).decode("ascii")
def init(data, ws):
w, h = len(data["colliders"][0]), len(data["colliders"])
current_user.loaded_world = {
"colliders": data["colliders"],
"objects": [[None for x in range(w)] for y in range(h)],
"owner": current_user.username,
}
current_user.claimed_base = ""
db.session.commit()
return current_user.loaded_world
def save(data, ws):
current_user.world = current_user.loaded_world
db.session.commit()
return current_user.world
def world(data, ws):
owner = data.get("owner", None)
if owner is None or not len(owner) or owner == current_user.username:
world = current_user.world
else:
world = User.query.filter(User.username == owner).first().world
current_user.loaded_world = world
db.session.commit()
return current_user.loaded_world
def put_object(data, ws):
location = data["location"]
object = data["item"]
if current_user.loaded_world["colliders"][location[0]][location[1]] is True:
raise AssertionError("you can't put objects in a wall.")
object_owner = data.get("owner", current_user.username)
if object_owner is None or not len(object_owner):
object_owner = current_user.username
if current_user.loaded_world["owner"] != current_user.username:
owner = User.query.filter(User.username == current_user.loaded_world["owner"]).first()
if f"{location[0]}x{location[1]}" in owner.claimed_base.split(","):
raise AssertionError("you can't put objects in someone else's base.")
current_user.loaded_world["objects"][location[0]][location[1]] = {"type": str(object), "owner": object_owner}
flag_modified(current_user, "loaded_world")
db.session.commit()
return current_user.loaded_world
def take_object(data, ws):
location = data["location"]
if current_user.loaded_world["owner"] != current_user.username:
owner = User.query.filter(User.username == current_user.loaded_world["owner"]).first()
if f"{location[0]}x{location[1]}" in owner.claimed_base.split(","):
raise AssertionError("you can't take objects from someone else's base.")
current_user.loaded_world["objects"][location[0]][location[1]] = None
flag_modified(current_user, "loaded_world")
db.session.commit()
return current_user.loaded_world
def push(data, ws):
location = data["location"]
if current_user.loaded_world["objects"][location[0]][location[1]] is None:
raise AssertionError("nothing to push.")
if current_user.loaded_world["owner"] != current_user.username:
owner = User.query.filter(User.username == current_user.loaded_world["owner"]).first()
if f"{location[0]}x{location[1]}" in owner.claimed_base.split(","):
raise AssertionError("you can't push objects in someone else's base.")
if current_user.loaded_world["objects"][location[0]][location[1]]["type"] == "book":
raise AssertionError("you can't push books.")
direction = data["direction"]
if direction == "u":
i, j = 1, 0
elif direction == "d":
i, j = -1, 0
elif direction == "r":
i, j = 0, 1
elif direction == "l":
i, j = 0, -1
else:
raise AssertionError("bad direction.")
y, x = location
colliders = current_user.loaded_world["colliders"]
objects = current_user.loaded_world["objects"]
last = objects[y][x]
objects[y][x] = None
ok = False
for k in range(2):
y += i
x += j
if colliders[y][x] is True:
db.session.rollback()
raise AssertionError("you can't push objects into wall.")
current = objects[y][x]
objects[y][x] = last
if current is None:
ok = True
break
last = current
if not ok:
db.session.rollback()
raise AssertionError("you can only push 2 objects in a row.")
flag_modified(current_user, "loaded_world")
db.session.commit()
return current_user.loaded_world
def claim_base(data, ws):
location = data["location"]
if current_user.loaded_world["owner"] != current_user.username:
owner = User.query.filter(User.username == current_user.loaded_world["owner"]).first()
if f"{location[0]}x{location[1]}" in owner.claimed_base.split(","):
raise AssertionError("you can't claim someone else's base")
t = f"{location[0]}x{location[1]},"
if t not in current_user.claimed_base:
current_user.claimed_base += t
db.session.commit()
if current_user.loaded_world["owner"] != current_user.username:
return {"claimedBase": current_user.claimed_base, "ownerBase": owner.claimed_base}
else:
return {"claimedBase": current_user.claimed_base}
def unclaim_base(data, ws):
location = data["location"]
current_user.claimed_base = current_user.claimed_base.replace(f"{location[0]}x{location[1]},", "")
db.session.commit()
if current_user.loaded_world["owner"] != current_user.username:
owner = User.query.filter(User.username == current_user.loaded_world["owner"]).first()
return {"claimedBase": current_user.claimed_base, "ownerBase": owner.claimed_base}
else:
return {"claimedBase": current_user.claimed_base}
def get_base(data, ws):
if current_user.loaded_world["owner"] != current_user.username:
owner = User.query.filter(User.username == current_user.loaded_world["owner"]).first()
return {"claimedBase": current_user.claimed_base, "ownerBase": owner.claimed_base}
else:
return {"claimedBase": current_user.claimed_base}
def set_inventory(data, ws):
location = data["location"]
object = current_user.loaded_world["objects"][location[0]][location[1]]
if object is None or object["type"] != "book":
raise AssertionError("inventory can only be accessed trough a book.")
if object["owner"] != current_user.username:
raise AssertionError("this book is not yours.")
current_user.inventory = data["inventory"]
db.session.commit()
return {"inventory": current_user.inventory}
def get_inventory(data, ws):
location = data["location"]
object = current_user.loaded_world["objects"][location[0]][location[1]]
if object is None or object["type"] != "book":
raise AssertionError("inventory can only be accessed trough a book.")
if object["owner"] != current_user.username:
raise AssertionError("this book is not yours.")
if current_user.loaded_world["owner"] != current_user.username:
owner = User.query.filter(User.username == current_user.loaded_world["owner"]).first()
if f"{location[0]}x{location[1]}" in owner.claimed_base:
return {"inventory": owner.inventory}
return {"inventory": current_user.inventory}
request_handlers = {
"claim_base": claim_base,
"get_base": get_base,
"get_inventory": get_inventory,
"init": init,
"push": push,
"put_object": put_object,
"save": save,
"set_inventory": set_inventory,
"take_object": take_object,
"unclaim_base": unclaim_base,
"world": world,
}
@game.route("/sock", websocket=True)
@login_required
def sock():
ws = simple_websocket.Server(request.environ)
try:
while True:
try:
data = json.loads(ws.receive())
if not isinstance(data, dict):
raise AssertionError("invalid request")
r = data.get("request", None)
if r not in request_handlers:
raise AssertionError("bad request")
ret = request_handlers[r](data, ws)
except json.JSONDecodeError:
traceback.print_exc()
ret = unparsable_msg
except simple_websocket.ws.ConnectionClosed:
ret = None
except AssertionError as e:
# traceback.print_exc()
# ret = {"ok": False}
ret = {"ok": False, "error": str(e)}
# ret = {"ok": False, "error": repr(e)}
# ret = {"ok": False, "error": traceback.format_exc()}
except Exception as e:
traceback.print_exc()
# ret = {"ok": False}
# ret = {"ok": False, "error": str(e)}
ret = {"ok": False, "error": repr(e)}
# ret = {"ok": False, "error": traceback.format_exc()}
if ret is not None:
ws.send(json.dumps(ret))
else:
ws.send(ok_msg)
except simple_websocket.ConnectionClosed:
pass
return ""

15
flask/init.sh Executable file
View File

@ -0,0 +1,15 @@
#!/bin/bash
set -e
here="$(realpath "$(dirname "$0")")"
cd "$here"
echo "---------- generate https certificate ----------"
openssl req -x509 -newkey RSA:4096 -keyform PEM -keyout "./key.pem" -outform PEM -out "./cert.pem" -days 3650 --nodes -subj "/CN="
echo "---------- link game ----------"
ln -sf "../../unity/game/Builds/WebGL" "./static/game"
realpath "."
cd "$here"
echo "---------- done ----------"

3
flask/models/__init__.py Executable file
View File

@ -0,0 +1,3 @@
from server import db
from .user import User

44
flask/models/user.py Executable file
View File

@ -0,0 +1,44 @@
from argon2 import PasswordHasher
from argon2.exceptions import VerifyMismatchError
from flask_login import UserMixin
from server import db
hasher = PasswordHasher()
class User(UserMixin, db.Model):
__tablename__ = "user"
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.Unicode, unique=True, nullable=False)
password = db.Column(db.String, nullable=False)
world = db.Column(db.JSON, nullable=True, default=None)
claimed_base = db.Column(db.JSON, nullable=False, default="")
inventory = db.Column(db.Unicode, nullable=True, default=None)
loaded_world = db.Column(db.JSON, nullable=True, default=None)
def get_id(self):
return str(self.id)
@classmethod
def exists(cls, username):
return cls.query.filter(cls.username == username).first() is not None
@classmethod
def register(cls, username, password, roles=None):
user = cls.query.filter(cls.username == username).first()
if user is None:
user = cls(username=username)
db.session.add(user)
user.password = hasher.hash(password)
db.session.commit()
return user
def verify(self, password):
try:
hasher.verify(self.password, password)
except VerifyMismatchError:
return False
if hasher.check_needs_rehash(self.password):
self.password = hasher.hash(password)
db.session.commit()
return True

10
flask/requirements.txt Executable file
View File

@ -0,0 +1,10 @@
argon2-cffi
flask
flask-login
flask-sqlalchemy
flask-sslify
flask-talisman
flask-wtf
gunicorn
simple-websocket
sqlalchemy

162
flask/server.py Executable file
View File

@ -0,0 +1,162 @@
import os
import secrets
from datetime import timedelta
from flask import Flask, abort
from flask_login import LoginManager
from flask_sqlalchemy import SQLAlchemy
from flask_sslify import SSLify
from flask_talisman import Talisman
from flask_talisman.talisman import ONE_YEAR_IN_SECS
from flask_wtf.csrf import CSRFProtect
domain = None # "127.0.0.1:8000"
# domain = f"dungeonsandexploits.team{team_number}.m0lecon.fans"
app = Flask(__name__)
# init sslify
sslify = SSLify(app)
# init talisman
talisman = Talisman(
app,
content_security_policy_nonce_in=["script-src", "style-src"],
# content_security_policy_nonce_in=["script-src", "style-src"],
content_security_policy_report_only=False,
content_security_policy_report_uri=None,
content_security_policy={ # do not add stuff here, put tags in html template tags: nonce="{{ csp_nonce() }}"
"default-src": "'none'",
# "script-src": "'self'",
"script-src": "'self' 'wasm-unsafe-eval'", # MAYBE THIS SHOULD NOT BE LIKE THIS BUT UNITY NEEDS IT
"style-src": "'self'",
"img-src": "'self'",
"connect-src": "'self'",
"base-uri": "'none'",
"form-action": "'none'",
"frame-ancestors": "'none'",
"strict-dynamic": "",
},
feature_policy={},
force_file_save=True,
force_https_permanent=True,
force_https=True,
frame_options_allow_from=None,
frame_options="DENY",
referrer_policy="strict-origin-when-cross-origin",
session_cookie_http_only=True,
session_cookie_secure=True,
strict_transport_security_include_subdomains=True,
strict_transport_security_max_age=ONE_YEAR_IN_SECS,
strict_transport_security_preload=False, # SOULD BE TRUE, enables HSTS preloading if you register your application with Google's HSTS preload list, Firefox and Chrome will never load your site over a non-secure connection.
strict_transport_security=True,
)
# init session
app.config.update(
APPLICATION_ROOT="/",
JSON_AS_ASCII=True,
JSON_SORT_KEYS=False,
JSONIFY_MIMETYPE="application/json",
JSONIFY_PRETTYPRINT_REGULAR=False,
MAX_CONTENT_LENGTH=16 * 1000 * 1000,
MAX_COOKIE_SIZE=4093,
PERMANENT_SESSION_LIFETIME=timedelta(minutes=30),
PREFERRED_URL_SCHEME="https",
SECRET_KEY=secrets.token_hex(256),
SEND_FILE_MAX_AGE_DEFAULT=timedelta(hours=12),
SERVER_NAME=domain,
SESSION_COOKIE_DOMAIN=domain,
SESSION_COOKIE_HTTPONLY=True,
SESSION_COOKIE_NAME="session",
SESSION_COOKIE_PATH="/",
SESSION_COOKIE_SAMESITE="Strict",
SESSION_COOKIE_SECURE=True,
SESSION_REFRESH_EACH_REQUEST=True,
USE_X_SENDFILE=False, # disabled: does not work with gunicorn
)
# init flask-wtf
app.config.update(
# RECAPTCHA_API_SERVER=None,
# RECAPTCHA_DATA_ATTRS=None,
# RECAPTCHA_DIV_CLASS="g-recaptcha",
# RECAPTCHA_HTML=None,
# RECAPTCHA_PARAMETERS=None,
# RECAPTCHA_PRIVATE_KEY=None,
# RECAPTCHA_PUBLIC_KEY=None,
# RECAPTCHA_SCRIPT="https://www.google.com/recaptcha/api.js",
# RECAPTCHA_VERIFY_SERVER="https://www.google.com/recaptcha/api/siteverify",
WTF_CSRF_CHECK_DEFAULT=True,
WTF_CSRF_ENABLED=True,
WTF_CSRF_FIELD_NAME="csrf_token",
WTF_CSRF_HEADERS=["X-CSRFToken", "X-CSRF-Token"],
WTF_CSRF_METHODS={"POST", "PUT", "PATCH", "DELETE"},
WTF_CSRF_SECRET_KEY=secrets.token_hex(256),
WTF_CSRF_SSL_STRICT=True,
WTF_CSRF_TIME_LIMIT=1200,
WTF_I18N_ENABLED=True,
)
csrfprotect = CSRFProtect(app)
# init flask-login
app.config.update(
AUTH_HEADER_NAME="Authorization",
COOKIE_DURATION=timedelta(minutes=30),
COOKIE_HTTPONLY=True,
COOKIE_NAME="remember_token",
COOKIE_SAMESITE=True,
COOKIE_SECURE=True,
EXEMPT_METHODS=set(),
LOGIN_MESSAGE_CATEGORY="message",
LOGIN_MESSAGE="Please log in to access this page.",
REFRESH_MESSAGE_CATEGORY="message",
REFRESH_MESSAGE="Please reauthenticate to access this page.",
REMEMBER_COOKIE_DOMAIN=domain,
REMEMBER_COOKIE_DURATION=timedelta(minutes=30),
REMEMBER_COOKIE_HTTPONLY=True,
REMEMBER_COOKIE_NAME="remember_token",
REMEMBER_COOKIE_PATH="/",
REMEMBER_COOKIE_REFRESH_EACH_REQUEST=True,
REMEMBER_COOKIE_SECURE=True,
# SESSION_KEYS=set(["_user_id", "_remember", "_remember_seconds", "_id", "_fresh", "next", ]),
SESSION_PROTECTION="strong",
USE_SESSION_FOR_NEXT=True,
)
login_manager = LoginManager(app)
# init flask-sqlalchemy
app.config.update(
# SQLALCHEMY_DATABASE_URI="sqlite:///:memory:?cache=shared",
SQLALCHEMY_DATABASE_URI="sqlite:////tmp/db.db",
# SQLALCHEMY_BINDS={},
# SQLALCHEMY_ECHO=True,
# SQLALCHEMY_RECORD_QUERIES=True,
SQLALCHEMY_TRACK_MODIFICATIONS=False,
# SQLALCHEMY_ENGINE_OPTIONS={},
)
db = SQLAlchemy(app)
def register_blueprints(app):
from auth import auth
from game import game
from website import website
app.register_blueprint(auth)
app.register_blueprint(website)
app.register_blueprint(game)
register_blueprints(app)
with app.app_context():
# create all missing db tables
db.create_all()
@app.route("/teapot")
async def teapot():
abort(418)
if __name__ == '__main__':
app.run()

4
flask/static/css/common.css Executable file
View File

@ -0,0 +1,4 @@
.fill-screen {
min-height: 100vh;
min-width: 100vw;
}

BIN
flask/static/img/favicon.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

97
flask/static/js/debug_index.js Executable file
View File

@ -0,0 +1,97 @@
const container = document.querySelector("#unity-container");
const canvas = document.querySelector("#unity-canvas");
const loadingBar = document.querySelector("#unity-loading-bar");
const progressBarFull = document.querySelector("#unity-progress-bar-full");
const fullscreenButton = document.querySelector("#unity-fullscreen-button");
const warningBanner = document.querySelector("#unity-warning");
// Shows a temporary message banner/ribbon for a few seconds, or
// a permanent error message on top of the canvas if type=="error".
// If type=="warning", a yellow highlight color is used.
// Modify or remove this function to customize the visually presented
// way that non-critical warnings and error messages are presented to the
// user.
function unityShowBanner(msg, type) {
function updateBannerVisibility() {
warningBanner.style.display = warningBanner.children.length ? "block" : "none";
}
const div = document.createElement("div");
div.innerHTML = msg;
warningBanner.appendChild(div);
if (type == "error") {
div.style = "background: red; padding: 10px;";
} else {
if (type == "warning") {
div.style = "background: yellow; padding: 10px;";
}
setTimeout(() => {
warningBanner.removeChild(div);
updateBannerVisibility();
}, 5000);
}
updateBannerVisibility();
}
const baseUrl = "/static/game";
const buildUrl = `${baseUrl}/Build`;
const loaderUrl = `${buildUrl}/WebGL.loader.js`;
const config = {
dataUrl: `${buildUrl}/WebGL.data`,
frameworkUrl: `${buildUrl}/WebGL.framework.js`,
codeUrl: `${buildUrl}/WebGL.wasm`,
streamingAssetsUrl: `${baseUrl}/StreamingAssets`,
companyName: "DefaultCompany",
productName: "game",
productVersion: "1.0",
showBanner: unityShowBanner
};
// By default Unity keeps WebGL canvas render target size matched with
// the DOM size of the canvas element (scaled by window.devicePixelRatio)
// Set this to false if you want to decouple this synchronization from
// happening inside the engine, and you would instead like to size up
// the canvas DOM size and WebGL render target sizes yourself.
// config.matchWebGLToCanvasSize = false;
if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
// Mobile device style: fill the whole browser client area with the game canvas:
const meta = document.createElement("meta");
meta.name = "viewport";
meta.content = "width=device-width, height=device-height, initial-scale=1.0, user-scalable=no, shrink-to-fit=yes";
document.getElementsByTagName("head")[0].appendChild(meta);
container.className = "unity-mobile";
canvas.className = "unity-mobile";
// To lower canvas resolution on mobile devices to gain some
// performance, uncomment the following line:
// config.devicePixelRatio = 1;
} else {
// Desktop style: Render the game canvas in a window that can be maximized to fullscreen:
canvas.style.width = "960px";
canvas.style.height = "600px";
}
loadingBar.style.display = "block";
const script = document.createElement("script");
script.src = loaderUrl;
script.onload = () => {
createUnityInstance(canvas, config, progress => {
progressBarFull.style.width = `${100 * progress}%`;
}).then(unityInstance => {
loadingBar.style.display = "none";
fullscreenButton.onclick = () => {
unityInstance.SetFullscreen(1);
};
}).catch(message => {
alert(message);
});
};
document.body.appendChild(script);

97
flask/static/js/index.js Executable file
View File

@ -0,0 +1,97 @@
const container = document.querySelector("#unity-container");
const canvas = document.querySelector("#unity-canvas");
const loadingBar = document.querySelector("#unity-loading-bar");
const progressBarFull = document.querySelector("#unity-progress-bar-full");
const fullscreenButton = document.querySelector("#unity-fullscreen-button");
const warningBanner = document.querySelector("#unity-warning");
// Shows a temporary message banner/ribbon for a few seconds, or
// a permanent error message on top of the canvas if type=='error'.
// If type=='warning', a yellow highlight color is used.
// Modify or remove this function to customize the visually presented
// way that non-critical warnings and error messages are presented to the
// user.
function unityShowBanner(msg, type) {
function updateBannerVisibility() {
warningBanner.style.display = warningBanner.children.length ? "block" : "none";
}
const div = document.createElement("div");
div.innerHTML = msg;
warningBanner.appendChild(div);
if (type == "error") {
div.style = "background: red; padding: 10px;";
} else {
if (type == "warning") {
div.style = "background: yellow; padding: 10px;";
}
setTimeout(() => {
warningBanner.removeChild(div);
updateBannerVisibility();
}, 5000);
}
updateBannerVisibility();
}
const baseUrl = "/static/game";
const buildUrl = `${baseUrl}/Build`;
const loaderUrl = `${buildUrl}/WebGL.loader.js`;
const config = {
dataUrl: `${buildUrl}/WebGL.data.br`,
frameworkUrl: `${buildUrl}/WebGL.framework.js.br`,
codeUrl: `${buildUrl}/WebGL.wasm.br`,
streamingAssetsUrl: `${baseUrl}/StreamingAssets`,
companyName: "DefaultCompany",
productName: "game",
productVersion: "1.0",
showBanner: unityShowBanner
};
// By default Unity keeps WebGL canvas render target size matched with
// the DOM size of the canvas element (scaled by window.devicePixelRatio)
// Set this to false if you want to decouple this synchronization from
// happening inside the engine, and you would instead like to size up
// the canvas DOM size and WebGL render target sizes yourself.
// config.matchWebGLToCanvasSize = false;
if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
// Mobile device style: fill the whole browser client area with the game canvas:
const meta = document.createElement("meta");
meta.name = "viewport";
meta.content = "width=device-width, height=device-height, initial-scale=1.0, user-scalable=no, shrink-to-fit=yes";
document.getElementsByTagName("head")[0].appendChild(meta);
container.className = "unity-mobile";
canvas.className = "unity-mobile";
// To lower canvas resolution on mobile devices to gain some
// performance, uncomment the following line:
// config.devicePixelRatio = 1;
} else {
// Desktop style: Render the game canvas in a window that can be maximized to fullscreen:
canvas.style.width = "960px";
canvas.style.height = "600px";
}
loadingBar.style.display = "block";
const script = document.createElement("script");
script.src = loaderUrl;
script.onload = () => {
createUnityInstance(canvas, config, progress => {
progressBarFull.style.width = `${100 * progress}%`;
}).then(unityInstance => {
loadingBar.style.display = "none";
fullscreenButton.onclick = () => {
unityInstance.SetFullscreen(1);
};
}).catch(message => {
alert(message);
});
};
document.body.appendChild(script);

31
flask/templates/base.html Executable file
View File

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="en">
<head>
{% block head %}
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}Dungeons & Exploits{% endblock %}</title>
<link rel="shortcut icon" href="{{ url_for('static', filename='img/favicon.png') }}">
<!-- JQuery -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous" nonce="{{ csp_nonce() }}"></script>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous" nonce="{{ csp_nonce() }}">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js" integrity="sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13" crossorigin="anonymous" nonce="{{ csp_nonce() }}"></script>
<!-- Custom -->
<link rel="stylesheet" href="{{ url_for('static', filename='css/common.css') }}">
{% endblock %}
</head>
<html>
<body class="fill-screen d-flex flex-column justify-content-start align-items-stretch bg-dark text-light">
{% block header %}{% endblock %}
{% block content %}{% endblock %}
{% block footer %}{% endblock %}
</body>
</html>

View File

@ -0,0 +1,25 @@
{% extends "base.html" %}
{% block head %}
{{ super() }}
<link rel="stylesheet" href="/static/game/TemplateData/style.css">
{% endblock %}
{% block content %}
<div id="unity-container" class="unity-desktop">
<canvas id="unity-canvas" width=960 height=600></canvas>
<div id="unity-loading-bar">
<div id="unity-logo"></div>
<div id="unity-progress-bar-empty">
<div id="unity-progress-bar-full"></div>
</div>
</div>
<div id="unity-warning"> </div>
<div id="unity-footer">
<div id="unity-webgl-logo"></div>
<div id="unity-fullscreen-button"></div>
<div id="unity-build-title">game</div>
</div>
<script src="{{ url_for('static', filename='js/debug_index.js') }}"></script>
</div>
{% endblock %}

25
flask/templates/index.html Executable file
View File

@ -0,0 +1,25 @@
{% extends "base.html" %}
{% block head %}
{{ super() }}
<link rel="stylesheet" href="/static/game/TemplateData/style.css">
{% endblock %}
{% block content %}
<div id="unity-container" class="unity-desktop">
<canvas id="unity-canvas" width=960 height=600></canvas>
<div id="unity-loading-bar">
<div id="unity-logo"></div>
<div id="unity-progress-bar-empty">
<div id="unity-progress-bar-full"></div>
</div>
</div>
<div id="unity-warning"> </div>
<div id="unity-footer">
<div id="unity-webgl-logo"></div>
<div id="unity-fullscreen-button"></div>
<div id="unity-build-title">game</div>
</div>
<script src="{{ url_for('static', filename='js/index.js') }}"></script>
</div>
{% endblock %}

26
flask/website.py Executable file
View File

@ -0,0 +1,26 @@
import base64
import json
import string
import traceback
import zlib
from time import time
from flask import Blueprint, redirect, render_template, url_for
from flask_login import current_user, login_required
website = Blueprint("website", __name__)
@website.route("/")
def index():
return render_template("index.html")
@website.route("/debug")
def debug_index():
return render_template("debug_index.html")
@website.route("/favicon.ico")
def favicon():
return redirect(url_for("static", filename="img/favicon.png"))

13
init.sh Executable file
View File

@ -0,0 +1,13 @@
#!/bin/bash
set -e
here="$(realpath "$(dirname "$0")")"
cd "$here"
echo "---------- build game ----------"
"./unity/build.sh"
echo "---------- run flask init.sh ----------"
"./flask/init.sh"
cd "$here"
echo "---------- done ----------"

6
load_dockers.sh Executable file
View File

@ -0,0 +1,6 @@
#!/bin/bash
set -e
here="$(realpath "$(dirname "$0")")"
cd "$here"
find "./saved" -iname "*.tar.xz" -type f | xargs -I {} -n 1 sh -c "cat {} | xz -d | docker load"

8
save_docker.sh Executable file
View File

@ -0,0 +1,8 @@
#!/bin/bash
set -e
here="$(realpath "$(dirname "$0")")"
cd "$here"
mkdir -p "./saved"
# echo -n ... | xargs -d " " ... if more than one image
echo "dungeonsandexploits" | xargs -I {} -n 1 sh -c "docker save '{}:latest' | xz > './saved/{}.tar.xz'"

23
unity/Unity_v2022.1.22f1.alf Executable file
View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<SystemInfo>
<IsoCode>C.UTF</IsoCode>
<UserName>root</UserName>
<OperatingSystem>Linux Ubuntu 64bit</OperatingSystem>
<OperatingSystemNumeric>600</OperatingSystemNumeric>
<ProcessorType>CPU</ProcessorType>
<ProcessorCount>0</ProcessorCount>
<PhysicalMemoryMB>0</PhysicalMemoryMB>
<ComputerName>000000000000</ComputerName>
<ComputerModel>PC</ComputerModel>
<UnityVersion>2022.1.22</UnityVersion>
<SupportedLicenseVersion>6.x</SupportedLicenseVersion>
</SystemInfo>
<License id="Terms">
<MachineBindings>
<Binding Key="1" Value="576562626572264761624c65526f7578"/>
<Binding Key="2" Value="576562626572264761624c65526f7578"/>
</MachineBindings><MachineID Value="D7nTUnjNAmtsUMcnoyrqkgIbYdM="/>
<UnityVersion Value="2022.1.22"/>
</License>
</root>

38
unity/Unity_v2022.x.ulf Executable file
View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?><root>
<License id="Terms">
<MachineBindings>
<Binding Key="1" Value="576562626572264761624c65526f7578"/>
<Binding Key="2" Value="576562626572264761624c65526f7578"/>
</MachineBindings>
<MachineID Value="D7nTUnjNAmtsUMcnoyrqkgIbYdM="/>
<SerialHash Value="72e60abd0b7b9eaf994e4c361632b8f988696064"/>
<Features>
<Feature Value="33"/>
<Feature Value="1"/>
<Feature Value="12"/>
<Feature Value="2"/>
<Feature Value="24"/>
<Feature Value="3"/>
<Feature Value="36"/>
<Feature Value="17"/>
<Feature Value="19"/>
<Feature Value="62"/>
</Features>
<DeveloperData Value="AQAAAEY0LUVFQVktWjdXMi1IOFdQLU1FR0MtVzZVUg=="/>
<SerialMasked Value="F4-EEAY-Z7W2-H8WP-MEGC-XXXX"/>
<StartDate Value="2022-08-23T00:00:00"/>
<UpdateDate Value="2022-11-12T14:49:22"/>
<InitialActivationDate Value="2022-08-23T08:49:37"/>
<LicenseVersion Value="6.x"/>
<ClientProvidedVersion Value="2022.1.22"/>
<AlwaysOnline Value="false"/>
<Entitlements>
<Entitlement Ns="unity_editor" Tag="UnityPersonal" Type="EDITOR" ValidTo="9999-12-31T00:00:00"/>
<Entitlement Ns="unity_editor" Tag="DarkSkin" Type="EDITOR_FEATURE" ValidTo="9999-12-31T00:00:00"/>
</Entitlements>
</License>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><Reference URI="#Terms"><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><DigestValue>ivspMx0LohiclfQqiypYM6jMA6E=</DigestValue></Reference></SignedInfo><SignatureValue>tZ5SBBofdLkOXMGYeO+RLuOhc9ExtzSup2ESVltdzHVsdLEdTn7JQy4xED5chUmONs0Ff32SLIWI&#13;
dhg5R8YYOUQ4W+zn4oAnVhtoCD5JYDZl2ZUxTWACsUf3UIksyDjLrvJOnfm1zdX18PR44RPxI4bW&#13;
wKF5PZvW1IfrsEPjRYpaRrhOFiIsEfUnpnH/QbJfVf2NS6OCKr4BxIavxsjHddf6jiuT/JAfYwy1&#13;
Br/dckYpe+5wHQYjYUqdOhWNe0eDEkshV5pBC2RzLCfmCkWoxQj35KLx4Uc5lj6LUx/Quf1w/cGR&#13;
sPgss+N4vz8CllSVOGNO0HJOXAs0/I12S+6rzw==</SignatureValue></Signature></root>

8
unity/build.sh Executable file
View File

@ -0,0 +1,8 @@
#!/bin/bash -e
cd "$(dirname "$0")"
"$HOME/Unity/Hub/Editor/2022.1.22f1/Editor/Unity" \
-quit -batchmode \
-logFile "/dev/stdout" \
-projectPath "./game/" \
-executeMethod "WebGLBuilder.Build"

72
unity/game/.gitignore vendored Executable file
View File

@ -0,0 +1,72 @@
# This .gitignore file should be placed at the root of your Unity project directory
#
# Get latest from https://github.com/github/gitignore/blob/main/Unity.gitignore
#
/[Ll]ibrary/
/[Tt]emp/
/[Oo]bj/
# /[Bb]uild/
# /[Bb]uilds/
/[Ll]ogs/
/[Uu]ser[Ss]ettings/
# MemoryCaptures can get excessive in size.
# They also could contain extremely sensitive data
/[Mm]emoryCaptures/
# Recordings can get excessive in size
/[Rr]ecordings/
# Uncomment this line if you wish to ignore the asset store tools plugin
# /[Aa]ssets/AssetStoreTools*
# Autogenerated Jetbrains Rider plugin
/[Aa]ssets/Plugins/Editor/JetBrains*
# Visual Studio cache directory
.vs/
# Gradle cache directory
.gradle/
# Autogenerated VS/MD/Consulo solution and project files
ExportedObj/
.consulo/
*.csproj
*.unityproj
*.sln
*.suo
*.tmp
*.user
*.userprefs
*.pidb
*.booproj
*.svd
*.pdb
*.mdb
*.opendb
*.VC.db
# Unity3D generated meta files
*.pidb.meta
*.pdb.meta
*.mdb.meta
# Unity3D generated file on crash reports
sysinfo.txt
# Builds
*.apk
*.aab
*.unitypackage
*.app
# Crashlytics generated file
crashlytics-build.properties
# Packed Addressables
/[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin*
# Temporary auto-generated Android Assets
/[Aa]ssets/[Ss]treamingAssets/aa.meta
/[Aa]ssets/[Ss]treamingAssets/aa/*

13
unity/game/.idea/.idea.game/.idea/.gitignore vendored Executable file
View File

@ -0,0 +1,13 @@
# Default ignored files
/shelf/
/workspace.xml
# Rider ignored files
/modules.xml
/contentModel.xml
/projectSettingsUpdater.xml
/.idea.game.iml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="Players.db" uuid="92dc17de-d1a2-44d8-960b-bc31f4aef0cb">
<driver-ref>sqlite.xerial</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
<jdbc-url>jdbc:sqlite:$PROJECT_DIR$/Players.db</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component>
</project>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
</project>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
</project>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="SqlDialectMappings">
<file url="file://$PROJECT_DIR$/Assets/Game/DatabaseManager.cs" dialect="GenericSQL" />
<file url="PROJECT" dialect="SQLite" />
</component>
</project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
</component>
</project>

8
unity/game/Assets/Art.meta Executable file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 756416a885ea9fbc69c5cd2869e2e6f3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 81a598884811f2e4c849253678a543fc
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3e08fad03e31a3b3cb61b3cce9d86b1a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,22 @@
fileFormatVersion: 2
guid: f70fa793f4e2b3be7adde4ea5502acd7
AudioImporter:
externalObjects: {}
serializedVersion: 6
defaultSettings:
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
preloadAudioData: 1
loadInBackground: 0
ambisonic: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3d9af60d63d112b389069bf2c42c67a3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,22 @@
fileFormatVersion: 2
guid: 54ab26afdb267c961a32db3a90f4d875
AudioImporter:
externalObjects: {}
serializedVersion: 6
defaultSettings:
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
preloadAudioData: 1
loadInBackground: 0
ambisonic: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,22 @@
fileFormatVersion: 2
guid: b2a1ec2c79522b5789735628d0b82acd
AudioImporter:
externalObjects: {}
serializedVersion: 6
defaultSettings:
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
preloadAudioData: 1
loadInBackground: 0
ambisonic: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,22 @@
fileFormatVersion: 2
guid: 0fdcf0e6b33c57a8a98f3012455e139e
AudioImporter:
externalObjects: {}
serializedVersion: 6
defaultSettings:
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
preloadAudioData: 1
loadInBackground: 0
ambisonic: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,22 @@
fileFormatVersion: 2
guid: fc5d149f7cdb90dd49940f3ebbb0d858
AudioImporter:
externalObjects: {}
serializedVersion: 6
defaultSettings:
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
preloadAudioData: 1
loadInBackground: 0
ambisonic: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,22 @@
fileFormatVersion: 2
guid: 3000a70851df4dd3a82fe3efde52f854
AudioImporter:
externalObjects: {}
serializedVersion: 6
defaultSettings:
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
preloadAudioData: 1
loadInBackground: 0
ambisonic: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,22 @@
fileFormatVersion: 2
guid: 74f45a513b4230f8bb934a68f84c83ab
AudioImporter:
externalObjects: {}
serializedVersion: 6
defaultSettings:
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
preloadAudioData: 1
loadInBackground: 0
ambisonic: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,22 @@
fileFormatVersion: 2
guid: 8fb78d58c41f8631bb974a4bc9fc4c8c
AudioImporter:
externalObjects: {}
serializedVersion: 6
defaultSettings:
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
preloadAudioData: 1
loadInBackground: 0
ambisonic: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,22 @@
fileFormatVersion: 2
guid: 7a72686bafd8c3542bef99d2a8e4c904
AudioImporter:
externalObjects: {}
serializedVersion: 6
defaultSettings:
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
preloadAudioData: 1
loadInBackground: 0
ambisonic: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,22 @@
fileFormatVersion: 2
guid: 122e0a7c274f25664a8fed48b2e14962
AudioImporter:
externalObjects: {}
serializedVersion: 6
defaultSettings:
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
preloadAudioData: 1
loadInBackground: 0
ambisonic: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 69a99e6219976869a9d3a113de163bea
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 1010 B

View File

@ -0,0 +1,706 @@
fileFormatVersion: 2
guid: f81874fe47f5392c7b5220cb48cbd48c
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMasterTextureLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 0
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 2
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites:
- serializedVersion: 2
name: thief_0
rect:
serializedVersion: 2
x: 0
y: 19
width: 12
height: 13
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: 0
bones: []
spriteID: b2b813520fad3cd479906c5bf2ce6b2a
internalID: -561335589
vertices: []
indices:
edges: []
weights: []
- serializedVersion: 2
name: thief_1
rect:
serializedVersion: 2
x: 12
y: 19
width: 12
height: 13
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: 0
bones: []
spriteID: 183477b054c003855ac3f3dd9746df8c
internalID: 1758720592
vertices: []
indices:
edges: []
weights: []
- serializedVersion: 2
name: thief_2
rect:
serializedVersion: 2
x: 24
y: 19
width: 12
height: 13
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: 0
bones: []
spriteID: cad572979e42da1ada8f55582da98a6a
internalID: -1664920418
vertices: []
indices:
edges: []
weights: []
- serializedVersion: 2
name: thief_3
rect:
serializedVersion: 2
x: 36
y: 19
width: 12
height: 13
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: 0
bones: []
spriteID: 6997125e7b3836d26a689d70502f545e
internalID: 1768772626
vertices: []
indices:
edges: []
weights: []
- serializedVersion: 2
name: thief_4
rect:
serializedVersion: 2
x: 48
y: 19
width: 12
height: 13
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: 0
bones: []
spriteID: 2fac64b061e890a3787da21fd36c53b3
internalID: 1103642258
vertices: []
indices:
edges: []
weights: []
- serializedVersion: 2
name: thief_5
rect:
serializedVersion: 2
x: 60
y: 19
width: 12
height: 13
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: 0
bones: []
spriteID: 3fa8916081dc61072b8b527d5c884b24
internalID: -1665220936
vertices: []
indices:
edges: []
weights: []
- serializedVersion: 2
name: thief_6
rect:
serializedVersion: 2
x: 72
y: 19
width: 12
height: 13
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: 0
bones: []
spriteID: 27cd038816eb88e4aab7694bd5f32825
internalID: 1438439708
vertices: []
indices:
edges: []
weights: []
- serializedVersion: 2
name: thief_7
rect:
serializedVersion: 2
x: 84
y: 19
width: 12
height: 13
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: 0
bones: []
spriteID: 33aaf5c5f6c6f275b8603605d83a8531
internalID: 368686970
vertices: []
indices:
edges: []
weights: []
- serializedVersion: 2
name: thief_8
rect:
serializedVersion: 2
x: 96
y: 19
width: 12
height: 13
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: 0
bones: []
spriteID: 7ed97f2b2c3d79e958dcc86d2d85e100
internalID: 365328370
vertices: []
indices:
edges: []
weights: []
- serializedVersion: 2
name: thief_9
rect:
serializedVersion: 2
x: 108
y: 19
width: 12
height: 13
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: 0
bones: []
spriteID: 395e80e035e212e27b8277e93eb2d5c6
internalID: 1036313572
vertices: []
indices:
edges: []
weights: []
- serializedVersion: 2
name: thief_10
rect:
serializedVersion: 2
x: 120
y: 19
width: 12
height: 13
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: 0
bones: []
spriteID: 68f703525ce94420aa83555205d02d0a
internalID: -1257812559
vertices: []
indices:
edges: []
weights: []
- serializedVersion: 2
name: thief_11
rect:
serializedVersion: 2
x: 132
y: 19
width: 12
height: 13
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: 0
bones: []
spriteID: 38a98b6072e9c2020a6643cab364cbc9
internalID: 1652228891
vertices: []
indices:
edges: []
weights: []
- serializedVersion: 2
name: thief_12
rect:
serializedVersion: 2
x: 144
y: 19
width: 12
height: 13
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: 0
bones: []
spriteID: dabb21e5eebcb8a19b9a3851ca8b07b6
internalID: 1947594230
vertices: []
indices:
edges: []
weights: []
- serializedVersion: 2
name: thief_13
rect:
serializedVersion: 2
x: 0
y: 6
width: 12
height: 13
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: 0
bones: []
spriteID: cb9a470a7e2d4e4e3a1622ce35119720
internalID: -319278449
vertices: []
indices:
edges: []
weights: []
- serializedVersion: 2
name: thief_14
rect:
serializedVersion: 2
x: 12
y: 6
width: 12
height: 13
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: 0
bones: []
spriteID: 9e165470c08f4f5c8a6b42a36fbcd10f
internalID: 987537855
vertices: []
indices:
edges: []
weights: []
- serializedVersion: 2
name: thief_15
rect:
serializedVersion: 2
x: 24
y: 6
width: 12
height: 13
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: 0
bones: []
spriteID: 536bb7cde210d2eb5b775a1acca59ffb
internalID: 1525115298
vertices: []
indices:
edges: []
weights: []
- serializedVersion: 2
name: thief_16
rect:
serializedVersion: 2
x: 36
y: 6
width: 12
height: 13
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: 0
bones: []
spriteID: 819923eb18bd0c863b71452ef8e1e079
internalID: 802537425
vertices: []
indices:
edges: []
weights: []
- serializedVersion: 2
name: thief_17
rect:
serializedVersion: 2
x: 48
y: 6
width: 12
height: 13
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: 0
bones: []
spriteID: f2faeddb6c77ca3df8f030196c18e167
internalID: 525619920
vertices: []
indices:
edges: []
weights: []
- serializedVersion: 2
name: thief_18
rect:
serializedVersion: 2
x: 60
y: 6
width: 12
height: 13
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: 0
bones: []
spriteID: dfff1fe32ada35e8090b1a7039113358
internalID: -250226704
vertices: []
indices:
edges: []
weights: []
- serializedVersion: 2
name: thief_19
rect:
serializedVersion: 2
x: 72
y: 6
width: 12
height: 13
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: 0
bones: []
spriteID: fd81c84315d91a725888a8d2e2bb8203
internalID: -2087255491
vertices: []
indices:
edges: []
weights: []
- serializedVersion: 2
name: thief_20
rect:
serializedVersion: 2
x: 84
y: 6
width: 12
height: 13
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: 0
bones: []
spriteID: 417163466d5465f499221e6302e15634
internalID: 502624055
vertices: []
indices:
edges: []
weights: []
- serializedVersion: 2
name: thief_21
rect:
serializedVersion: 2
x: 96
y: 6
width: 12
height: 13
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: 0
bones: []
spriteID: fef2f379b20baba6f86a4755f162b8e3
internalID: -2037557596
vertices: []
indices:
edges: []
weights: []
- serializedVersion: 2
name: thief_22
rect:
serializedVersion: 2
x: 108
y: 6
width: 12
height: 13
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: 0
bones: []
spriteID: 67635a051afe12fe49c619f172a0d487
internalID: 1054486716
vertices: []
indices:
edges: []
weights: []
- serializedVersion: 2
name: thief_23
rect:
serializedVersion: 2
x: 120
y: 6
width: 12
height: 13
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: 0
bones: []
spriteID: ed592210cbe2e91e79f0bf57dff27f56
internalID: -2120861284
vertices: []
indices:
edges: []
weights: []
- serializedVersion: 2
name: thief_24
rect:
serializedVersion: 2
x: 132
y: 6
width: 12
height: 13
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: 0
bones: []
spriteID: 8face607781e59065bbd9bdc8fd8de11
internalID: 1236021398
vertices: []
indices:
edges: []
weights: []
- serializedVersion: 2
name: thief_25
rect:
serializedVersion: 2
x: 144
y: 6
width: 12
height: 13
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: 0
bones: []
spriteID: 73cb2d7139ef488d584f5ebdc402a16a
internalID: 588575381
vertices: []
indices:
edges: []
weights: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable:
thief_23: -2120861284
thief_3: 1768772626
thief_18: -250226704
thief_11: 1652228891
thief_19: -2087255491
thief_7: 368686970
thief_20: 502624055
thief_24: 1236021398
thief_4: 1103642258
thief_9: 1036313572
thief_21: -2037557596
thief_6: 1438439708
thief_1: 1758720592
thief_15: 1525115298
thief_5: -1665220936
thief_10: -1257812559
thief_25: 588575381
thief_2: -1664920418
thief_13: -319278449
thief_12: 1947594230
thief_0: -561335589
thief_17: 525619920
thief_22: 1054486716
thief_14: 987537855
thief_16: 802537425
thief_8: 365328370
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8e214e55964e93122875b2e6391544a8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4ae5304042ca2a13bb0e4a177226e32e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,173 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using System;
public class Alive : MonoBehaviour {
protected Animator animator;
protected Rigidbody2D rigidBody;
protected SpriteRenderer spriteRenderer;
// Start is called before the first frame update
public void Start() {
animator = GetComponent<Animator>();
rigidBody = GetComponent<Rigidbody2D>();
spriteRenderer = GetComponent<SpriteRenderer>();
}
public void FixedUpdate() {
// MOVEMENT
TryMove();
}
public void OnFire() {
// ATTACK
Attack();
}
// MOVEMENT
public Vector2 movementInput = Vector2.zero;
public ContactFilter2D movementFilter;
public List<RaycastHit2D> castCollisions = new List<RaycastHit2D>();
public bool canMove = true;
public float moveSpeed = 1f;
public float collisionOffset = 0.01f;
[HideInInspector] public string direction = null;
public void OnMove(InputValue movementValue) {
movementInput = movementValue.Get<Vector2>();
}
private void TryMove() {
bool success;
if(canMove && movementInput != Vector2.zero) {
// If movement input is not 0, try to move
success = DoTryMove(movementInput);
if(!success) {
success = DoTryMove(new Vector2(movementInput.x, 0));
} else if(!success) {
success = DoTryMove(new Vector2(0, movementInput.y));
}
} else {
success = false;
}
if(movementInput.y > movementInput.x) {
if(movementInput.y > -movementInput.x) {
direction = "u";
} else {
direction = "l";
}
} else {
if(movementInput.y > -movementInput.x) {
direction = "r";
} else {
direction = "d";
}
}
// Set direction of sprite to movement direction
if(movementInput[0] < 0) {
spriteRenderer.flipX = true;
} else if (movementInput[0] > 0) {
spriteRenderer.flipX = false;
}
// Set animator moving flag
animator.SetBool("isMoving", success);
}
private bool DoTryMove(Vector2 direction) {
if(direction == Vector2.zero) {
// Can't move if there's no direction to move in
return false;
}
// Check for potential collisions
int count = rigidBody.Cast(
direction, // X and Y values between -1 and 1 that represent the direction from the body to look for collisions
movementFilter, // The settings that determine where a collision can occur on such as layers to collide with
castCollisions, // List of collisions to store the found collisions into after the Cast is finished
moveSpeed * Time.fixedDeltaTime + collisionOffset); // The amount to cast equal to the movement plus an offset
if(count == 0) {
rigidBody.MovePosition(rigidBody.position + direction * moveSpeed * Time.fixedDeltaTime);
return true;
}
return false;
}
public void LockMovement() {
canMove = false;
}
public void UnlockMovement() {
canMove = true;
}
// HEALTH
public float Health {
set {
health = value;
if(health <= 0) {
Defeated();
}
}
get {
return health;
}
}
public float health = 1f;
public void Hurt(float damage) {
Health -= damage;
animator.SetTrigger("hurt");
}
virtual public void Defeated() {
LockAttack();
LockMovement();
gameObject.GetComponent<Collider2D>().enabled = false;
animator.SetTrigger("defeated");
}
virtual public void Dead() {
Remove();
}
public void Remove() {
Destroy(gameObject);
}
// ATTACK
public bool canAttack = true;
public void Attack() {
if (canAttack) {
LockAttack();
LockMovement();
animator.SetTrigger("attack");
DoAttack();
}
}
public void LockAttack() {
canAttack = false;
}
virtual public void DoAttack() {}
public void EndAttack() {
DoEndAttack();
UnlockMovement();
UnlockAttack();
}
public void UnlockAttack() {
canAttack = true;
}
virtual public void DoEndAttack() {}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b3e177969b5161db78b99182d6545da6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,391 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1102 &-8490357743690569194
AnimatorState:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Walking
m_Speed: 1
m_CycleOffset: 0
m_Transitions:
- {fileID: 2505488881732398557}
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
m_WriteDefaultValues: 1
m_Mirror: 0
m_SpeedParameterActive: 0
m_MirrorParameterActive: 0
m_CycleOffsetParameterActive: 0
m_TimeParameterActive: 0
m_Motion: {fileID: 7400000, guid: db904536d53e2060ca91b5cb2565c773, type: 2}
m_Tag:
m_SpeedParameter:
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:
--- !u!1101 &-7444937961241257097
AnimatorStateTransition:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name:
m_Conditions:
- m_ConditionMode: 1
m_ConditionEvent: defeated
m_EventTreshold: 0
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: 7260894833331674536}
m_Solo: 0
m_Mute: 0
m_IsExit: 0
serializedVersion: 3
m_TransitionDuration: 0
m_TransitionOffset: 0
m_ExitTime: 1
m_HasExitTime: 1
m_HasFixedDuration: 0
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 1
--- !u!1107 &-6711984926992957811
AnimatorStateMachine:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Base Layer
m_ChildStates:
- serializedVersion: 1
m_State: {fileID: -5435647673510224127}
m_Position: {x: 300, y: 60, z: 0}
- serializedVersion: 1
m_State: {fileID: -8490357743690569194}
m_Position: {x: 600, y: 60, z: 0}
- serializedVersion: 1
m_State: {fileID: 6714635060549412509}
m_Position: {x: 300, y: -140, z: 0}
- serializedVersion: 1
m_State: {fileID: 6613775354220869138}
m_Position: {x: 300, y: -240, z: 0}
- serializedVersion: 1
m_State: {fileID: 7260894833331674536}
m_Position: {x: 600, y: -240, z: 0}
m_ChildStateMachines: []
m_AnyStateTransitions:
- {fileID: -1299932708819945340}
- {fileID: -5725769222568087913}
m_EntryTransitions: []
m_StateMachineTransitions: {}
m_StateMachineBehaviours: []
m_AnyStatePosition: {x: 40, y: -130, z: 0}
m_EntryPosition: {x: 40, y: 70, z: 0}
m_ExitPosition: {x: 900, y: 70, z: 0}
m_ParentStateMachinePosition: {x: 800, y: 20, z: 0}
m_DefaultState: {fileID: -5435647673510224127}
--- !u!1101 &-5725769222568087913
AnimatorStateTransition:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name:
m_Conditions:
- m_ConditionMode: 1
m_ConditionEvent: hurt
m_EventTreshold: 0
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: 6613775354220869138}
m_Solo: 0
m_Mute: 0
m_IsExit: 0
serializedVersion: 3
m_TransitionDuration: 0
m_TransitionOffset: 0
m_ExitTime: 1
m_HasExitTime: 0
m_HasFixedDuration: 0
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 1
--- !u!1102 &-5435647673510224127
AnimatorState:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Idle
m_Speed: 1
m_CycleOffset: 0
m_Transitions:
- {fileID: 4321696166490883550}
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
m_WriteDefaultValues: 1
m_Mirror: 0
m_SpeedParameterActive: 0
m_MirrorParameterActive: 0
m_CycleOffsetParameterActive: 0
m_TimeParameterActive: 0
m_Motion: {fileID: 7400000, guid: 849d44a5e35642b1c9ad137bfa084b77, type: 2}
m_Tag:
m_SpeedParameter:
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:
--- !u!1101 &-1299932708819945340
AnimatorStateTransition:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name:
m_Conditions:
- m_ConditionMode: 1
m_ConditionEvent: attack
m_EventTreshold: 0
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: 6714635060549412509}
m_Solo: 0
m_Mute: 0
m_IsExit: 0
serializedVersion: 3
m_TransitionDuration: 0
m_TransitionOffset: 0
m_ExitTime: 1
m_HasExitTime: 0
m_HasFixedDuration: 1
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 1
--- !u!91 &9100000
AnimatorController:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: AliveAnimatorController
serializedVersion: 5
m_AnimatorParameters:
- m_Name: isMoving
m_Type: 4
m_DefaultFloat: 0
m_DefaultInt: 0
m_DefaultBool: 0
m_Controller: {fileID: 0}
- m_Name: attack
m_Type: 9
m_DefaultFloat: 0
m_DefaultInt: 0
m_DefaultBool: 0
m_Controller: {fileID: 0}
- m_Name: hurt
m_Type: 9
m_DefaultFloat: 0
m_DefaultInt: 0
m_DefaultBool: 0
m_Controller: {fileID: 0}
- m_Name: defeated
m_Type: 9
m_DefaultFloat: 0
m_DefaultInt: 0
m_DefaultBool: 0
m_Controller: {fileID: 0}
m_AnimatorLayers:
- serializedVersion: 5
m_Name: Base Layer
m_StateMachine: {fileID: -6711984926992957811}
m_Mask: {fileID: 0}
m_Motions: []
m_Behaviours: []
m_BlendingMode: 0
m_SyncedLayerIndex: -1
m_DefaultWeight: 0
m_IKPass: 0
m_SyncedLayerAffectsTiming: 0
m_Controller: {fileID: 9100000}
--- !u!1101 &1170228230597471895
AnimatorStateTransition:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name:
m_Conditions:
- m_ConditionMode: 2
m_ConditionEvent: isMoving
m_EventTreshold: 0
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: -5435647673510224127}
m_Solo: 0
m_Mute: 0
m_IsExit: 0
serializedVersion: 3
m_TransitionDuration: 0
m_TransitionOffset: 0
m_ExitTime: 1
m_HasExitTime: 1
m_HasFixedDuration: 1
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 1
--- !u!1101 &2505488881732398557
AnimatorStateTransition:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name:
m_Conditions:
- m_ConditionMode: 2
m_ConditionEvent: isMoving
m_EventTreshold: 0
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: -5435647673510224127}
m_Solo: 0
m_Mute: 0
m_IsExit: 0
serializedVersion: 3
m_TransitionDuration: 0
m_TransitionOffset: 0
m_ExitTime: 1
m_HasExitTime: 1
m_HasFixedDuration: 1
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 1
--- !u!1101 &4321696166490883550
AnimatorStateTransition:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name:
m_Conditions:
- m_ConditionMode: 1
m_ConditionEvent: isMoving
m_EventTreshold: 0
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: -8490357743690569194}
m_Solo: 0
m_Mute: 0
m_IsExit: 0
serializedVersion: 3
m_TransitionDuration: 0
m_TransitionOffset: 0
m_ExitTime: 1
m_HasExitTime: 0
m_HasFixedDuration: 1
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 1
--- !u!1101 &5038610780791241483
AnimatorStateTransition:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name:
m_Conditions: []
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: 0}
m_Solo: 0
m_Mute: 0
m_IsExit: 1
serializedVersion: 3
m_TransitionDuration: 0
m_TransitionOffset: 0
m_ExitTime: 1
m_HasExitTime: 1
m_HasFixedDuration: 0
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 1
--- !u!1102 &6613775354220869138
AnimatorState:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Hurt
m_Speed: 1
m_CycleOffset: 0
m_Transitions:
- {fileID: -7444937961241257097}
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
m_WriteDefaultValues: 1
m_Mirror: 0
m_SpeedParameterActive: 0
m_MirrorParameterActive: 0
m_CycleOffsetParameterActive: 0
m_TimeParameterActive: 0
m_Motion: {fileID: 7400000, guid: aafba2923f73ad6f9ad127acaee9a298, type: 2}
m_Tag:
m_SpeedParameter:
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:
--- !u!1102 &6714635060549412509
AnimatorState:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Attack
m_Speed: 1
m_CycleOffset: 0
m_Transitions:
- {fileID: 1170228230597471895}
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
m_WriteDefaultValues: 1
m_Mirror: 0
m_SpeedParameterActive: 0
m_MirrorParameterActive: 0
m_CycleOffsetParameterActive: 0
m_TimeParameterActive: 0
m_Motion: {fileID: 7400000, guid: 3bff7c8a7d52e543dbcf79090bf8f80a, type: 2}
m_Tag:
m_SpeedParameter:
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:
--- !u!1102 &7260894833331674536
AnimatorState:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Die
m_Speed: 1
m_CycleOffset: 0
m_Transitions:
- {fileID: 5038610780791241483}
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
m_WriteDefaultValues: 1
m_Mirror: 0
m_SpeedParameterActive: 0
m_MirrorParameterActive: 0
m_CycleOffsetParameterActive: 0
m_TimeParameterActive: 0
m_Motion: {fileID: 7400000, guid: cde9a4883d5911ac9941c802b0cce93b, type: 2}
m_Tag:
m_SpeedParameter:
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b213cfcae91063b36802e9e49ddf1383
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 9100000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5e6ed504905805180aded68fc23ac6c7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,53 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!74 &7400000
AnimationClip:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Attack
serializedVersion: 7
m_Legacy: 0
m_Compressed: 0
m_UseHighQualityCurve: 1
m_RotationCurves: []
m_CompressedRotationCurves: []
m_EulerCurves: []
m_PositionCurves: []
m_ScaleCurves: []
m_FloatCurves: []
m_PPtrCurves: []
m_SampleRate: 60
m_WrapMode: 0
m_Bounds:
m_Center: {x: 0, y: 0, z: 0}
m_Extent: {x: 0, y: 0, z: 0}
m_ClipBindingConstant:
genericBindings: []
pptrCurveMapping: []
m_AnimationClipSettings:
serializedVersion: 2
m_AdditiveReferencePoseClip: {fileID: 0}
m_AdditiveReferencePoseTime: 0
m_StartTime: 0
m_StopTime: 1
m_OrientationOffsetY: 0
m_Level: 0
m_CycleOffset: 0
m_HasAdditiveReferencePose: 0
m_LoopTime: 0
m_LoopBlend: 0
m_LoopBlendOrientation: 0
m_LoopBlendPositionY: 0
m_LoopBlendPositionXZ: 0
m_KeepOriginalOrientation: 0
m_KeepOriginalPositionY: 1
m_KeepOriginalPositionXZ: 0
m_HeightFromFeet: 0
m_Mirror: 0
m_EditorCurves: []
m_EulerEditorCurves: []
m_HasGenericRootTransform: 0
m_HasMotionFloatCurves: 0
m_Events: []

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3bff7c8a7d52e543dbcf79090bf8f80a
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 7400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,53 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!74 &7400000
AnimationClip:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Die
serializedVersion: 7
m_Legacy: 0
m_Compressed: 0
m_UseHighQualityCurve: 1
m_RotationCurves: []
m_CompressedRotationCurves: []
m_EulerCurves: []
m_PositionCurves: []
m_ScaleCurves: []
m_FloatCurves: []
m_PPtrCurves: []
m_SampleRate: 60
m_WrapMode: 0
m_Bounds:
m_Center: {x: 0, y: 0, z: 0}
m_Extent: {x: 0, y: 0, z: 0}
m_ClipBindingConstant:
genericBindings: []
pptrCurveMapping: []
m_AnimationClipSettings:
serializedVersion: 2
m_AdditiveReferencePoseClip: {fileID: 0}
m_AdditiveReferencePoseTime: 0
m_StartTime: 0
m_StopTime: 1
m_OrientationOffsetY: 0
m_Level: 0
m_CycleOffset: 0
m_HasAdditiveReferencePose: 0
m_LoopTime: 0
m_LoopBlend: 0
m_LoopBlendOrientation: 0
m_LoopBlendPositionY: 0
m_LoopBlendPositionXZ: 0
m_KeepOriginalOrientation: 0
m_KeepOriginalPositionY: 1
m_KeepOriginalPositionXZ: 0
m_HeightFromFeet: 0
m_Mirror: 0
m_EditorCurves: []
m_EulerEditorCurves: []
m_HasGenericRootTransform: 0
m_HasMotionFloatCurves: 0
m_Events: []

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cde9a4883d5911ac9941c802b0cce93b
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 7400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,53 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!74 &7400000
AnimationClip:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Hurt
serializedVersion: 7
m_Legacy: 0
m_Compressed: 0
m_UseHighQualityCurve: 1
m_RotationCurves: []
m_CompressedRotationCurves: []
m_EulerCurves: []
m_PositionCurves: []
m_ScaleCurves: []
m_FloatCurves: []
m_PPtrCurves: []
m_SampleRate: 60
m_WrapMode: 0
m_Bounds:
m_Center: {x: 0, y: 0, z: 0}
m_Extent: {x: 0, y: 0, z: 0}
m_ClipBindingConstant:
genericBindings: []
pptrCurveMapping: []
m_AnimationClipSettings:
serializedVersion: 2
m_AdditiveReferencePoseClip: {fileID: 0}
m_AdditiveReferencePoseTime: 0
m_StartTime: 0
m_StopTime: 1
m_OrientationOffsetY: 0
m_Level: 0
m_CycleOffset: 0
m_HasAdditiveReferencePose: 0
m_LoopTime: 0
m_LoopBlend: 0
m_LoopBlendOrientation: 0
m_LoopBlendPositionY: 0
m_LoopBlendPositionXZ: 0
m_KeepOriginalOrientation: 0
m_KeepOriginalPositionY: 1
m_KeepOriginalPositionXZ: 0
m_HeightFromFeet: 0
m_Mirror: 0
m_EditorCurves: []
m_EulerEditorCurves: []
m_HasGenericRootTransform: 0
m_HasMotionFloatCurves: 0
m_Events: []

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: aafba2923f73ad6f9ad127acaee9a298
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 7400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,53 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!74 &7400000
AnimationClip:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Idle
serializedVersion: 7
m_Legacy: 0
m_Compressed: 0
m_UseHighQualityCurve: 1
m_RotationCurves: []
m_CompressedRotationCurves: []
m_EulerCurves: []
m_PositionCurves: []
m_ScaleCurves: []
m_FloatCurves: []
m_PPtrCurves: []
m_SampleRate: 60
m_WrapMode: 0
m_Bounds:
m_Center: {x: 0, y: 0, z: 0}
m_Extent: {x: 0, y: 0, z: 0}
m_ClipBindingConstant:
genericBindings: []
pptrCurveMapping: []
m_AnimationClipSettings:
serializedVersion: 2
m_AdditiveReferencePoseClip: {fileID: 0}
m_AdditiveReferencePoseTime: 0
m_StartTime: 0
m_StopTime: 1
m_OrientationOffsetY: 0
m_Level: 0
m_CycleOffset: 0
m_HasAdditiveReferencePose: 0
m_LoopTime: 0
m_LoopBlend: 0
m_LoopBlendOrientation: 0
m_LoopBlendPositionY: 0
m_LoopBlendPositionXZ: 0
m_KeepOriginalOrientation: 0
m_KeepOriginalPositionY: 1
m_KeepOriginalPositionXZ: 0
m_HeightFromFeet: 0
m_Mirror: 0
m_EditorCurves: []
m_EulerEditorCurves: []
m_HasGenericRootTransform: 0
m_HasMotionFloatCurves: 0
m_Events: []

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 849d44a5e35642b1c9ad137bfa084b77
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 7400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,53 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!74 &7400000
AnimationClip:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Walking
serializedVersion: 7
m_Legacy: 0
m_Compressed: 0
m_UseHighQualityCurve: 1
m_RotationCurves: []
m_CompressedRotationCurves: []
m_EulerCurves: []
m_PositionCurves: []
m_ScaleCurves: []
m_FloatCurves: []
m_PPtrCurves: []
m_SampleRate: 60
m_WrapMode: 0
m_Bounds:
m_Center: {x: 0, y: 0, z: 0}
m_Extent: {x: 0, y: 0, z: 0}
m_ClipBindingConstant:
genericBindings: []
pptrCurveMapping: []
m_AnimationClipSettings:
serializedVersion: 2
m_AdditiveReferencePoseClip: {fileID: 0}
m_AdditiveReferencePoseTime: 0
m_StartTime: 0
m_StopTime: 1
m_OrientationOffsetY: 0
m_Level: 0
m_CycleOffset: 0
m_HasAdditiveReferencePose: 0
m_LoopTime: 0
m_LoopBlend: 0
m_LoopBlendOrientation: 0
m_LoopBlendPositionY: 0
m_LoopBlendPositionXZ: 0
m_KeepOriginalOrientation: 0
m_KeepOriginalPositionY: 1
m_KeepOriginalPositionXZ: 0
m_HeightFromFeet: 0
m_Mirror: 0
m_EditorCurves: []
m_EulerEditorCurves: []
m_HasGenericRootTransform: 0
m_HasMotionFloatCurves: 0
m_Events: []

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: db904536d53e2060ca91b5cb2565c773
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 7400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c7ac03932ecf92217a69b174b92555d2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4c2246750b1fc87988231d8b6c93adee
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,90 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!74 &7400000
AnimationClip:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: EnemyAttack
serializedVersion: 7
m_Legacy: 0
m_Compressed: 0
m_UseHighQualityCurve: 1
m_RotationCurves: []
m_CompressedRotationCurves: []
m_EulerCurves: []
m_PositionCurves: []
m_ScaleCurves: []
m_FloatCurves: []
m_PPtrCurves:
- curve:
- time: 0
value: {fileID: 1757990579, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
- time: 0.06666667
value: {fileID: 321477455, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
- time: 0.15
value: {fileID: -1832914597, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
- time: 0.21666667
value: {fileID: 1149553823, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
- time: 0.28333333
value: {fileID: -70945730, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
- time: 0.35
value: {fileID: -959400664, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
- time: 0.43333334
value: {fileID: -1410030147, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
- time: 0.5
value: {fileID: -154032179, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
attribute: m_Sprite
path:
classID: 212
script: {fileID: 0}
m_SampleRate: 60
m_WrapMode: 0
m_Bounds:
m_Center: {x: 0, y: 0, z: 0}
m_Extent: {x: 0, y: 0, z: 0}
m_ClipBindingConstant:
genericBindings:
- serializedVersion: 2
path: 0
attribute: 0
script: {fileID: 0}
typeID: 212
customType: 23
isPPtrCurve: 1
isIntCurve: 0
pptrCurveMapping:
- {fileID: 1757990579, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
- {fileID: 321477455, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
- {fileID: -1832914597, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
- {fileID: 1149553823, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
- {fileID: -70945730, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
- {fileID: -959400664, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
- {fileID: -1410030147, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
- {fileID: -154032179, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
m_AnimationClipSettings:
serializedVersion: 2
m_AdditiveReferencePoseClip: {fileID: 0}
m_AdditiveReferencePoseTime: 0
m_StartTime: 0
m_StopTime: 0.51666665
m_OrientationOffsetY: 0
m_Level: 0
m_CycleOffset: 0
m_HasAdditiveReferencePose: 0
m_LoopTime: 1
m_LoopBlend: 0
m_LoopBlendOrientation: 0
m_LoopBlendPositionY: 0
m_LoopBlendPositionXZ: 0
m_KeepOriginalOrientation: 0
m_KeepOriginalPositionY: 1
m_KeepOriginalPositionXZ: 0
m_HeightFromFeet: 0
m_Mirror: 0
m_EditorCurves: []
m_EulerEditorCurves: []
m_HasGenericRootTransform: 0
m_HasMotionFloatCurves: 0
m_Events: []

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7e2f02b79f967c7b4be2506aa2e5b15f
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 7400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,85 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!74 &7400000
AnimationClip:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: EnemyDie
serializedVersion: 7
m_Legacy: 0
m_Compressed: 0
m_UseHighQualityCurve: 1
m_RotationCurves: []
m_CompressedRotationCurves: []
m_EulerCurves: []
m_PositionCurves: []
m_ScaleCurves: []
m_FloatCurves: []
m_PPtrCurves:
- curve:
- time: 0
value: {fileID: 795076807, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
- time: 0.25
value: {fileID: -38419174, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
- time: 0.5
value: {fileID: 708132321, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
- time: 0.75
value: {fileID: 708132321, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
attribute: m_Sprite
path:
classID: 212
script: {fileID: 0}
m_SampleRate: 60
m_WrapMode: 0
m_Bounds:
m_Center: {x: 0, y: 0, z: 0}
m_Extent: {x: 0, y: 0, z: 0}
m_ClipBindingConstant:
genericBindings:
- serializedVersion: 2
path: 0
attribute: 0
script: {fileID: 0}
typeID: 212
customType: 23
isPPtrCurve: 1
isIntCurve: 0
pptrCurveMapping:
- {fileID: 795076807, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
- {fileID: -38419174, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
- {fileID: 708132321, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
- {fileID: 708132321, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
m_AnimationClipSettings:
serializedVersion: 2
m_AdditiveReferencePoseClip: {fileID: 0}
m_AdditiveReferencePoseTime: 0
m_StartTime: 0
m_StopTime: 0.76666665
m_OrientationOffsetY: 0
m_Level: 0
m_CycleOffset: 0
m_HasAdditiveReferencePose: 0
m_LoopTime: 1
m_LoopBlend: 0
m_LoopBlendOrientation: 0
m_LoopBlendPositionY: 0
m_LoopBlendPositionXZ: 0
m_KeepOriginalOrientation: 0
m_KeepOriginalPositionY: 1
m_KeepOriginalPositionXZ: 0
m_HeightFromFeet: 0
m_Mirror: 0
m_EditorCurves: []
m_EulerEditorCurves: []
m_HasGenericRootTransform: 0
m_HasMotionFloatCurves: 0
m_Events:
- time: 0.75
functionName: Dead
data:
objectReferenceParameter: {fileID: 0}
floatParameter: 0
intParameter: 0
messageOptions: 0

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 10ef1021fc3e918bc9647b613a9c78a3
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 7400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,53 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!74 &7400000
AnimationClip:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: EnemyHurt
serializedVersion: 7
m_Legacy: 0
m_Compressed: 0
m_UseHighQualityCurve: 1
m_RotationCurves: []
m_CompressedRotationCurves: []
m_EulerCurves: []
m_PositionCurves: []
m_ScaleCurves: []
m_FloatCurves: []
m_PPtrCurves: []
m_SampleRate: 60
m_WrapMode: 0
m_Bounds:
m_Center: {x: 0, y: 0, z: 0}
m_Extent: {x: 0, y: 0, z: 0}
m_ClipBindingConstant:
genericBindings: []
pptrCurveMapping: []
m_AnimationClipSettings:
serializedVersion: 2
m_AdditiveReferencePoseClip: {fileID: 0}
m_AdditiveReferencePoseTime: 0
m_StartTime: 0
m_StopTime: 1
m_OrientationOffsetY: 0
m_Level: 0
m_CycleOffset: 0
m_HasAdditiveReferencePose: 0
m_LoopTime: 1
m_LoopBlend: 0
m_LoopBlendOrientation: 0
m_LoopBlendPositionY: 0
m_LoopBlendPositionXZ: 0
m_KeepOriginalOrientation: 0
m_KeepOriginalPositionY: 1
m_KeepOriginalPositionXZ: 0
m_HeightFromFeet: 0
m_Mirror: 0
m_EditorCurves: []
m_EulerEditorCurves: []
m_HasGenericRootTransform: 0
m_HasMotionFloatCurves: 0
m_Events: []

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b40e8739fe15a0f728344efe01e9c51c
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 7400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,78 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!74 &7400000
AnimationClip:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: EnemyIdle
serializedVersion: 7
m_Legacy: 0
m_Compressed: 0
m_UseHighQualityCurve: 1
m_RotationCurves: []
m_CompressedRotationCurves: []
m_EulerCurves: []
m_PositionCurves: []
m_ScaleCurves: []
m_FloatCurves: []
m_PPtrCurves:
- curve:
- time: 0
value: {fileID: 134074492, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
- time: 1
value: {fileID: -154032179, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
- time: 1.5
value: {fileID: 134074492, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
- time: 2.5
value: {fileID: 134074492, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
attribute: m_Sprite
path:
classID: 212
script: {fileID: 0}
m_SampleRate: 60
m_WrapMode: 0
m_Bounds:
m_Center: {x: 0, y: 0, z: 0}
m_Extent: {x: 0, y: 0, z: 0}
m_ClipBindingConstant:
genericBindings:
- serializedVersion: 2
path: 0
attribute: 0
script: {fileID: 0}
typeID: 212
customType: 23
isPPtrCurve: 1
isIntCurve: 0
pptrCurveMapping:
- {fileID: 134074492, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
- {fileID: -154032179, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
- {fileID: 134074492, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
- {fileID: 134074492, guid: 904aaab31c7ac9c48a8c213a8e5551c6, type: 3}
m_AnimationClipSettings:
serializedVersion: 2
m_AdditiveReferencePoseClip: {fileID: 0}
m_AdditiveReferencePoseTime: 0
m_StartTime: 0
m_StopTime: 2.5166667
m_OrientationOffsetY: 0
m_Level: 0
m_CycleOffset: 0
m_HasAdditiveReferencePose: 0
m_LoopTime: 1
m_LoopBlend: 0
m_LoopBlendOrientation: 0
m_LoopBlendPositionY: 0
m_LoopBlendPositionXZ: 0
m_KeepOriginalOrientation: 0
m_KeepOriginalPositionY: 1
m_KeepOriginalPositionXZ: 0
m_HeightFromFeet: 0
m_Mirror: 0
m_EditorCurves: []
m_EulerEditorCurves: []
m_HasGenericRootTransform: 0
m_HasMotionFloatCurves: 0
m_Events: []

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 27178e59bad688c79928be8b7b8ff0ec
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 7400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,53 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!74 &7400000
AnimationClip:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: EnemyWalk
serializedVersion: 7
m_Legacy: 0
m_Compressed: 0
m_UseHighQualityCurve: 1
m_RotationCurves: []
m_CompressedRotationCurves: []
m_EulerCurves: []
m_PositionCurves: []
m_ScaleCurves: []
m_FloatCurves: []
m_PPtrCurves: []
m_SampleRate: 60
m_WrapMode: 0
m_Bounds:
m_Center: {x: 0, y: 0, z: 0}
m_Extent: {x: 0, y: 0, z: 0}
m_ClipBindingConstant:
genericBindings: []
pptrCurveMapping: []
m_AnimationClipSettings:
serializedVersion: 2
m_AdditiveReferencePoseClip: {fileID: 0}
m_AdditiveReferencePoseTime: 0
m_StartTime: 0
m_StopTime: 1
m_OrientationOffsetY: 0
m_Level: 0
m_CycleOffset: 0
m_HasAdditiveReferencePose: 0
m_LoopTime: 1
m_LoopBlend: 0
m_LoopBlendOrientation: 0
m_LoopBlendPositionY: 0
m_LoopBlendPositionXZ: 0
m_KeepOriginalOrientation: 0
m_KeepOriginalPositionY: 1
m_KeepOriginalPositionXZ: 0
m_HeightFromFeet: 0
m_Mirror: 0
m_EditorCurves: []
m_EulerEditorCurves: []
m_HasGenericRootTransform: 0
m_HasMotionFloatCurves: 0
m_Events: []

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1472c5bd14d9338c69b1df1d0253086b
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 7400000
userData:
assetBundleName:
assetBundleVariant:

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