Initial commit
This commit is contained in:
11
pp/oppai-ng/.gitignore
vendored
Normal file
11
pp/oppai-ng/.gitignore
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
tags
|
||||
*.log
|
||||
*.tar.xz
|
||||
*.zip
|
||||
/oppai
|
||||
*.json
|
||||
*.obj
|
||||
*.exe
|
||||
*.swp
|
||||
/test/test_suite
|
||||
/test/oppai_test
|
22
pp/oppai-ng/.travis.yml
Normal file
22
pp/oppai-ng/.travis.yml
Normal file
@@ -0,0 +1,22 @@
|
||||
language: c
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
dist: precise
|
||||
- os: linux
|
||||
dist: trusty
|
||||
- os: osx
|
||||
|
||||
|
||||
install: true
|
||||
cache:
|
||||
directories:
|
||||
- test/test_suite
|
||||
|
||||
script:
|
||||
- ./build
|
||||
- cd test
|
||||
- ./download_suite
|
||||
- ./build
|
||||
- ./oppai_test
|
349
pp/oppai-ng/README.md
Normal file
349
pp/oppai-ng/README.md
Normal file
@@ -0,0 +1,349 @@
|
||||
[](https://travis-ci.org/Francesco149/oppai-ng)
|
||||
|
||||
difficulty and pp calculator for osu!
|
||||
|
||||
this is a pure C89 rewrite of
|
||||
[oppai](https://github.com/Francesco149/oppai) with much lower
|
||||
memory usage, smaller and easier to read codebase
|
||||
executable size and better performance.
|
||||
|
||||
experimental taiko support is now available and appears to give
|
||||
correct values for actual taiko maps. converted maps are still
|
||||
unreliable due to incorrect slider conversion and might be
|
||||
completely off (use ```-m1``` or ```-taiko``` to convert a std map
|
||||
to taiko).
|
||||
|
||||
- [installing (linux)](#installing-linux)
|
||||
- [installing (windows)](#installing-windows)
|
||||
- [installing (osx)](#installing-osx)
|
||||
- [usage](#usage)
|
||||
- [implementations for other programming languages](#implementations-for-other-programming-languages)
|
||||
- [oppai-ng vs old oppai](#oppai-ng-vs-old-oppai)
|
||||
- [compile from source (windows)](#compile-from-source-windows)
|
||||
- [using oppai as a library or making bindings](#using-oppai-as-a-library-or-making-bindings)
|
||||
- [other build parameters](#other-build-parameters)
|
||||
|
||||
# installing (linux)
|
||||
```sh
|
||||
wget https://github.com/Francesco149/oppai-ng/archive/HEAD.tar.gz
|
||||
tar xf HEAD.tar.gz
|
||||
cd oppai-*
|
||||
./build
|
||||
sudo install -Dm 755 oppai /usr/bin/oppai
|
||||
|
||||
oppai
|
||||
```
|
||||
|
||||
you can also grab pre-compiled standalone binaries (statically
|
||||
linked against musl libc) from
|
||||
[here](https://github.com/Francesco149/oppai-ng/releases) if you
|
||||
are somehow too scared to run those 5 commands.
|
||||
|
||||
# installing (windows)
|
||||
download and unzip binaries from
|
||||
[here](https://github.com/Francesco149/oppai-ng/releases) and
|
||||
optionally add oppai's folder to your ```PATH``` environment
|
||||
variable for easy access. you can find a guide
|
||||
[here](https://www.howtogeek.com/118594/how-to-edit-your-system-path-for-easy-command-line-access/)
|
||||
if you don't know how.
|
||||
|
||||
# installing (osx)
|
||||
## via homebrew
|
||||
```sh
|
||||
brew install --HEAD pmrowla/homebrew-tap/oppai-ng
|
||||
```
|
||||
Note that installing with ```--HEAD``` is recommended but not required.
|
||||
Installing from homebrew will place the ```oppai``` executable in your homebrew path.
|
||||
|
||||
## manually
|
||||
Follow the same steps as for linux but substitute ```curl -O``` for ```wget``` since wget is not distributed by default in osx.
|
||||
The same caveat applies if you want to run the test suite - you will need to edit the ```download_suite``` script to use curl.
|
||||
|
||||
# usage
|
||||
you can run oppai with no arguments to check the documentation.
|
||||
|
||||
here's some example usages:
|
||||
|
||||
```sh
|
||||
oppai path/to/map.osu +HDHR 98% 500x 1xmiss
|
||||
oppai path/to/map.osu 3x100
|
||||
oppai path/to/map.osu 3x100 OD10
|
||||
oppai path/to/map.osu -ojson
|
||||
```
|
||||
|
||||
you can also pipe maps from standard input by setting the filename
|
||||
to ```-```.
|
||||
|
||||
for example on linux you can do:
|
||||
|
||||
```sh
|
||||
curl https://osu.ppy.sh/osu/774965 | oppai - +HDDT
|
||||
curl https://osu.ppy.sh/osu/774965 | oppai - +HDDT 1200x 1m
|
||||
```
|
||||
|
||||
while on windows it's a bit more verbose (powershell):
|
||||
|
||||
```powershell
|
||||
(New-Object System.Net.WebClient).DownloadString("https://osu.ppy.sh/osu/37658") | ./oppai -
|
||||
(New-Object System.Net.WebClient).DownloadString("https://osu.ppy.sh/osu/37658") | ./oppai - +HDHR
|
||||
(New-Object System.Net.WebClient).DownloadString("https://osu.ppy.sh/osu/37658") | ./oppai - +HDHR 99% 600x 1m
|
||||
```
|
||||
|
||||
I got the .osu file url from "Grab latest .osu file" on the
|
||||
beatmap's page.
|
||||
|
||||
# implementations for other programming languages
|
||||
oppai has been implemented for many other programming languages.
|
||||
If you feel like making your own implementation and want it listed
|
||||
here, open an issue or pull request. the requirement is that it
|
||||
should pass the same test suite that oppai-ng passes.
|
||||
|
||||
note: these aren't just native bindings unless stated otherwise.
|
||||
|
||||
* [ojsama (javascript)](https://github.com/Francesco149/ojsama)
|
||||
* [koohii (java)](https://github.com/Francesco149/koohii) . this
|
||||
is currently being used in tillerino.
|
||||
* [pyttanko (python)](https://github.com/Francesco149/pyttanko)
|
||||
* [oppai5 (golang)](https://github.com/flesnuk/oppai5) (by flesnuk)
|
||||
* [OppaiSharp (C#)](https://github.com/HoLLy-HaCKeR/OppaiSharp)
|
||||
(by HoLLy)
|
||||
|
||||
# oppai-ng vs old oppai
|
||||
executable size is around 7 times smaller:
|
||||
```sh
|
||||
$ cd ~/src/oppai
|
||||
$ ./build.sh -static
|
||||
$ wc -c oppai
|
||||
574648 oppai
|
||||
|
||||
$ cd ~/src/oppai-ng
|
||||
$ ./build -static
|
||||
$ wc -c oppai
|
||||
75512 oppai
|
||||
```
|
||||
|
||||
oppai-ng has proper error output in whatever format you select,
|
||||
while legacy oppai either gives empty output or just dies with
|
||||
a plaintext error.
|
||||
|
||||
oppai-ng has well-defined errno style error codes that you can
|
||||
check for when using it as a library or reading its output.
|
||||
|
||||
the same test suite runs about 45% faster on oppai-ng compared
|
||||
to old oppai, also the peak resident memory size is 4 to 6 times
|
||||
smaller according to various ```time -v``` runs.
|
||||
|
||||
```sh
|
||||
$ cd ~/src/oppai
|
||||
$ ./build_test.sh
|
||||
$ time -v ./oppai_test
|
||||
...
|
||||
Command being timed: "./oppai_test"
|
||||
User time (seconds): 13.89
|
||||
System time (seconds): 0.10
|
||||
Percent of CPU this job got: 99%
|
||||
Elapsed (wall clock) time (h:mm:ss or m:ss): 0m 13.99s
|
||||
Average shared text size (kbytes): 0
|
||||
Average unshared data size (kbytes): 0
|
||||
Average stack size (kbytes): 0
|
||||
Average total size (kbytes): 0
|
||||
Maximum resident set size (kbytes): 45184
|
||||
Average resident set size (kbytes): 0
|
||||
Major (requiring I/O) page faults: 0
|
||||
Minor (reclaiming a frame) page faults: 2143
|
||||
Voluntary context switches: 1
|
||||
Involuntary context switches: 41
|
||||
Swaps: 0
|
||||
File system inputs: 0
|
||||
File system outputs: 0
|
||||
Socket messages sent: 0
|
||||
Socket messages received: 0
|
||||
Signals delivered: 0
|
||||
Page size (bytes): 4096
|
||||
Exit status: 0
|
||||
|
||||
$ cd ~/src/oppai-ng/test/
|
||||
$ ./build
|
||||
$ time -v ./oppai_test
|
||||
...
|
||||
Command being timed: "./oppai_test"
|
||||
User time (seconds): 9.09
|
||||
System time (seconds): 0.06
|
||||
Percent of CPU this job got: 99%
|
||||
Elapsed (wall clock) time (h:mm:ss or m:ss): 0m 9.15s
|
||||
Average shared text size (kbytes): 0
|
||||
Average unshared data size (kbytes): 0
|
||||
Average stack size (kbytes): 0
|
||||
Average total size (kbytes): 0
|
||||
Maximum resident set size (kbytes): 11840
|
||||
Average resident set size (kbytes): 0
|
||||
Major (requiring I/O) page faults: 0
|
||||
Minor (reclaiming a frame) page faults: 304
|
||||
Voluntary context switches: 1
|
||||
Involuntary context switches: 39
|
||||
Swaps: 0
|
||||
File system inputs: 0
|
||||
File system outputs: 0
|
||||
Socket messages sent: 0
|
||||
Socket messages received: 0
|
||||
Signals delivered: 0
|
||||
Page size (bytes): 4096
|
||||
Exit status: 0
|
||||
```
|
||||
|
||||
note that when the test suite is compiled without libcurl, the
|
||||
resident memory usage drops by a flat 4mb, so almost half of that
|
||||
is curl.
|
||||
|
||||
you can expect oppai memory usage to be under 4 mb most of the time
|
||||
with the raw parsed beatmap data not taking more than ~800k even
|
||||
for a 15 minute marathon.
|
||||
|
||||
the codebase has ~3-4x less lines than legacy oppai, making it easy
|
||||
to read and use as a single header library. not only it is smaller,
|
||||
but it now also implements both taiko and osu, so more features
|
||||
than legacy oppai.
|
||||
|
||||
the osu! pp and diff calc alone would be around ~3k LOC including
|
||||
the cli, which would be 5x less lines than legacy oppai for the
|
||||
same functionality.
|
||||
|
||||
```sh
|
||||
$ cd ~/src/oppai
|
||||
$ sloc *.cc
|
||||
|
||||
---------- Result ------------
|
||||
|
||||
Physical : 15310
|
||||
Source : 14406
|
||||
Comment : 301
|
||||
Single-line comment : 289
|
||||
Block comment : 12
|
||||
Mixed : 23
|
||||
Empty : 626
|
||||
To Do : 11
|
||||
|
||||
Number of files read : 10
|
||||
|
||||
------------------------------
|
||||
|
||||
$ cd ~/src/oppai-ng
|
||||
$ sloc *.c
|
||||
|
||||
---------- Result ------------
|
||||
|
||||
Physical : 4123
|
||||
Source : 2906
|
||||
Comment : 492
|
||||
Single-line comment : 1
|
||||
Block comment : 491
|
||||
Mixed : 64
|
||||
Empty : 811
|
||||
To Do : 9
|
||||
|
||||
Number of files read : 2
|
||||
|
||||
------------------------------
|
||||
```
|
||||
|
||||
not to mention it's C89, which will be compatible with many more
|
||||
platforms and old compilers than c++98
|
||||
|
||||
```oppai.c``` alone is only ~2200 LOC (~1500 without comments), and
|
||||
you can compile piece of it out when you don't need them.
|
||||
|
||||
of course, it's not as heavily tested as legacy oppai (which runs
|
||||
24/7 on Tillerino's back-end), however the test suite is a very
|
||||
good test that runs through ~12000 unique scores and I'm confident
|
||||
this rewrite is already very stable.
|
||||
|
||||
# compile from source (windows)
|
||||
oppai should compile even on old versions of msvc dating back to
|
||||
2005, although it was only tested on msvc 2010 and higher.
|
||||
|
||||
have at least [microsoft c++ build tools](http://landinghub.visualstudio.com/visual-cpp-build-tools)
|
||||
installed. visual studio with c/c++ support also works.
|
||||
|
||||
open a visual studio prompt:
|
||||
|
||||
```bat
|
||||
cd path\to\oppai\source
|
||||
build.bat
|
||||
oppai
|
||||
```
|
||||
|
||||
you can also probably set up mingw and cygwin and follow the linux
|
||||
instructions instead, I'm not sure. I don't use windows.
|
||||
|
||||
# using oppai as a library or making bindings
|
||||
the new codebase is much easier to isolate and include in your
|
||||
projects.
|
||||
|
||||
just copy oppai.c into your project, it acts as a single-header
|
||||
library.
|
||||
|
||||
```c
|
||||
#define OPPAI_IMPLEMENTATION
|
||||
#include "../oppai.c"
|
||||
|
||||
int main()
|
||||
{
|
||||
struct parser pstate;
|
||||
struct beatmap map;
|
||||
|
||||
uint32_t mods;
|
||||
struct diff_calc stars;
|
||||
struct pp_calc pp;
|
||||
|
||||
p_init(&pstate);
|
||||
p_map(&pstate, &map, stdin);
|
||||
|
||||
mods = MODS_HD | MODS_DT;
|
||||
|
||||
d_init(&stars);
|
||||
d_calc(&stars, &map, mods);
|
||||
printf("%g stars\n", stars.total);
|
||||
|
||||
b_ppv2(&map, &pp, stars.aim, stars.speed, mods);
|
||||
printf("%gpp\n", pp.total);
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
```sh
|
||||
gcc test.c
|
||||
cat /path/to/file.osu | ./a.out
|
||||
```
|
||||
|
||||
read oppai.c, there's documentation for each function at the top.
|
||||
|
||||
see examples directory for detailed examples. you can also read
|
||||
main.c to see how the CLI uses it.
|
||||
|
||||
oppai is also modular, you can define out parts of the code
|
||||
that you don't use by defining any of:
|
||||
```
|
||||
OPPAI_NOPARSER
|
||||
OPPAI_NOPP
|
||||
OPPAI_NODIFFCALC
|
||||
```
|
||||
|
||||
if you don't feel comfortable writing bindings or using oppai
|
||||
from c code, you can use the -o parameter to output in json or
|
||||
other parsable formats. ```examples/binary.c``` shows how to parse
|
||||
the binary output.
|
||||
|
||||
# other build parameters
|
||||
when you build the oppai cli, you can pass any of these parameters
|
||||
to the build script to disable features:
|
||||
|
||||
* ```-DOPPAI_NOTEXT``` disables text output module
|
||||
* ```-DOPPAI_NOJSON``` disables json output module
|
||||
* ```-DOPPAI_NOCSV``` disables CSV output module
|
||||
* ```-DOPPAI_NOBINARY``` disables binary output module
|
||||
* ```-DOPPAI_DEBUG``` enables debug output module and memory usage
|
||||
statistics
|
||||
* ```-DOPPAI_NOSTDINT``` doesn't use ```stdint.h```, as some
|
||||
machines or old compilers don't have it
|
||||
|
24
pp/oppai-ng/UNLICENSE
Normal file
24
pp/oppai-ng/UNLICENSE
Normal file
@@ -0,0 +1,24 @@
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <http://unlicense.org/>
|
11
pp/oppai-ng/build.bat
Normal file
11
pp/oppai-ng/build.bat
Normal file
@@ -0,0 +1,11 @@
|
||||
@echo off
|
||||
|
||||
del oppai.exe >nul 2>&1
|
||||
del oppai.obj >nul 2>&1
|
||||
cl -D_CRT_SECURE_NO_WARNINGS=1 ^
|
||||
-DNOMINMAX=1 ^
|
||||
-O2 ^
|
||||
-nologo -MT -Gm- -GR- -EHsc -W4 ^
|
||||
main.c ^
|
||||
-Feoppai.exe ^
|
||||
|| EXIT /B 1
|
10
pp/oppai-ng/build_containers
Normal file
10
pp/oppai-ng/build_containers
Normal file
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
dir=$(dirname $0)
|
||||
for d in $dir/docker/*
|
||||
do
|
||||
bn=$(basename $d)
|
||||
cp $d/Dockerfile .
|
||||
docker build -t "oppai-ng:$bn" .
|
||||
rm Dockerfile
|
||||
done
|
7
pp/oppai-ng/build_containers.ps1
Normal file
7
pp/oppai-ng/build_containers.ps1
Normal file
@@ -0,0 +1,7 @@
|
||||
$dir = Split-Path -Parent $MyInvocation.MyCommand.Definition
|
||||
Push-Location "$dir"
|
||||
$d = "docker/windows"
|
||||
Copy-Item $d/Dockerfile .
|
||||
docker build -t "oppai-ng:windows" .
|
||||
Remove-Item Dockerfile
|
||||
Pop-Location
|
34
pp/oppai-ng/cflags
Normal file
34
pp/oppai-ng/cflags
Normal file
@@ -0,0 +1,34 @@
|
||||
#!/bin/sh
|
||||
|
||||
cflags="-std=c89 -pedantic"
|
||||
cflags="$cflags -O3"
|
||||
cflags="$cflags -fno-strict-aliasing"
|
||||
cflags="$cflags -Wno-variadic-macros -Wno-long-long -Wall"
|
||||
cflags="$cflags -ffunction-sections -fdata-sections"
|
||||
cflags="$cflags -g0 -fno-unwind-tables -s"
|
||||
cflags="$cflags -fno-asynchronous-unwind-tables"
|
||||
|
||||
ldflags="-lm"
|
||||
|
||||
cflags="$cflags $CFLAGS"
|
||||
ldflags="$ldflags $LDFLAGS"
|
||||
|
||||
cc="$CC"
|
||||
|
||||
if [ $(uname) = "Darwin" ]; then
|
||||
cc=${cc:-clang}
|
||||
else
|
||||
cc=${cc:-gcc}
|
||||
fi
|
||||
|
||||
uname -a > flags.log
|
||||
echo $cc >> flags.log
|
||||
echo $cflags >> flags.log
|
||||
echo $ldflags >> flags.log
|
||||
$cc --version >> flags.log
|
||||
$cc -dumpmachine >> flags.log
|
||||
|
||||
export cflags="$cflags"
|
||||
export ldflags="$ldflags"
|
||||
export cc="$cc"
|
||||
|
5
pp/oppai-ng/docker/musl-x86/Dockerfile
Normal file
5
pp/oppai-ng/docker/musl-x86/Dockerfile
Normal file
@@ -0,0 +1,5 @@
|
||||
FROM multiarch/alpine:x86-latest-stable
|
||||
|
||||
RUN apk add --no-cache musl-dev gcc git xz
|
||||
WORKDIR /tmp
|
||||
CMD [ "sh", "./release" ]
|
5
pp/oppai-ng/docker/musl-x86_64/Dockerfile
Normal file
5
pp/oppai-ng/docker/musl-x86_64/Dockerfile
Normal file
@@ -0,0 +1,5 @@
|
||||
FROM multiarch/alpine:x86_64-latest-stable
|
||||
|
||||
RUN apk add --no-cache musl-dev gcc git xz
|
||||
WORKDIR /tmp
|
||||
CMD [ "sh", "./release" ]
|
26
pp/oppai-ng/docker/windows/Dockerfile
Normal file
26
pp/oppai-ng/docker/windows/Dockerfile
Normal file
@@ -0,0 +1,26 @@
|
||||
# escape=`
|
||||
|
||||
# I wanted to use nanoserver but I couldn't get visual c++ build
|
||||
# tools to install. the nuget visual c++ build tools package isn't
|
||||
# enough to get a working compiler and manually copying msvc
|
||||
# defeats the purpose of using the container to automatically
|
||||
# install deps.
|
||||
# unfortunately windowsservercore is a 4GB image
|
||||
FROM microsoft/windowsservercore
|
||||
|
||||
RUN @"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
|
||||
|
||||
# wait for vs_installer.exe, vs_installerservice.exe
|
||||
# or vs_installershell.exe because choco doesn't
|
||||
RUN powershell -NoProfile -InputFormat None -Command `
|
||||
choco install git 7zip -y; `
|
||||
choco install visualcpp-build-tools `
|
||||
--version 15.0.26228.20170424 -y; `
|
||||
Write-Host 'Waiting for Visual C++ Build Tools to finish'; `
|
||||
Wait-Process -Name vs_installer
|
||||
|
||||
WORKDIR C:\oppai-ng
|
||||
CMD powershell -ExecutionPolicy Bypass -Command `
|
||||
Get-Location; Get-ChildItem; `
|
||||
. .\vcvarsall17.ps1 x64; .\release.ps1; `
|
||||
. .\vcvarsall17.ps1 x86; .\release.ps1
|
10
pp/oppai-ng/package
Normal file
10
pp/oppai-ng/package
Normal file
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
dir=$(dirname $0)
|
||||
dir=$(readlink -f $dir)
|
||||
prevdir=$(pwd)
|
||||
cd $dir
|
||||
for d in $dir/docker/*; do
|
||||
docker run --rm -v $dir:/tmp oppai-ng:$(basename $d)
|
||||
done
|
||||
cd $prevdir
|
4
pp/oppai-ng/package.ps1
Normal file
4
pp/oppai-ng/package.ps1
Normal file
@@ -0,0 +1,4 @@
|
||||
$dir = Split-Path -Parent $MyInvocation.MyCommand.Definition
|
||||
Push-Location $dir
|
||||
docker run --rm -v ${dir}:c:\oppai-ng oppai-ng:windows
|
||||
Pop-Location
|
36
pp/oppai-ng/release
Normal file
36
pp/oppai-ng/release
Normal file
@@ -0,0 +1,36 @@
|
||||
#!/bin/sh
|
||||
|
||||
dir=$(dirname $0)
|
||||
|
||||
olddir=$(pwd)
|
||||
cd $dir
|
||||
git pull origin master
|
||||
|
||||
echo -e "\nCompiling and Stripping"
|
||||
./build -static -no-pie || exit 1
|
||||
|
||||
echo -e "\nPackaging"
|
||||
folder="oppai-$(./oppai -version)-"
|
||||
folder="${folder}$(gcc -dumpmachine)"
|
||||
|
||||
mkdir -p "$folder"
|
||||
mv ./oppai $folder/oppai
|
||||
git archive HEAD --prefix=src/ -o "$folder"/src.tar
|
||||
cd "$folder"
|
||||
tar xf src.tar
|
||||
cd ..
|
||||
|
||||
rm "$folder".tar.xz
|
||||
tar -cvJf "$folder".tar.xz \
|
||||
"$folder"/oppai \
|
||||
"$folder"/src
|
||||
|
||||
echo -e "\nResult:"
|
||||
tar tf "$folder".tar.xz
|
||||
|
||||
readelf --dynamic "$folder"/oppai
|
||||
ldd "$folder"/oppai
|
||||
|
||||
rm -rf "$folder"
|
||||
cd $olddir
|
||||
|
42
pp/oppai-ng/release.ps1
Normal file
42
pp/oppai-ng/release.ps1
Normal file
@@ -0,0 +1,42 @@
|
||||
# you must allow script execution by running
|
||||
# 'Set-ExecutionPolicy RemoteSigned' in an admin powershell
|
||||
# this requires vcvars to be already set (see vcvarsall17.ps1)
|
||||
# 7zip is also required (choco install 7zip and add it to path)
|
||||
|
||||
$dir = Split-Path -Parent $MyInvocation.MyCommand.Definition
|
||||
|
||||
Push-Location "$dir"
|
||||
git pull origin master -q
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "########################" -Foreground Yellow -Background Black
|
||||
Write-Host "> Compiling and stripping" -Foreground Yellow -Background Black
|
||||
cmd /c "build.bat"
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "########################" -Foreground Yellow -Background Black
|
||||
Write-Host "> Packaging" -Foreground Yellow -Background Black
|
||||
$folder = "oppai-" + $(.\oppai.exe -version) + "-windows-"
|
||||
$clout = & cl 2>&1 | %{ "$_" }
|
||||
"$clout" -match "(Microsoft.*for )([a-z0-9\-_]+)" | Out-Null
|
||||
$folder = $folder + $Matches[2]
|
||||
mkdir $folder
|
||||
Copy-Item oppai.exe $folder
|
||||
git archive HEAD --prefix=src\ -o $folder\src.zip
|
||||
Set-Location $folder
|
||||
&7z x src.zip
|
||||
Set-Location ..
|
||||
|
||||
if (Test-Path "$folder.zip") {
|
||||
Remove-Item "$folder.zip"
|
||||
}
|
||||
|
||||
&7z a "$folder.zip" $folder\oppai.exe $folder\src
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "########################" -Foreground Yellow -Background Black
|
||||
Write-Host "> Result:" -Foreground Yellow -Background Black
|
||||
&7z l "$folder.zip"
|
||||
|
||||
Remove-Item $folder -Force -Recurse
|
||||
Pop-Location
|
10
pp/oppai-ng/test/download_suite
Normal file
10
pp/oppai-ng/test/download_suite
Normal file
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ $(find test_suite 2>/dev/null | tail -n +2 | wc -l) = "0" ]
|
||||
then
|
||||
wget http://www.hnng.moe/stuff/test_suite_20180515.tar.xz \
|
||||
|| exit 1
|
||||
tar xf test_suite_20180515.tar.xz || exit 1
|
||||
else
|
||||
echo "using existing test_suite"
|
||||
fi
|
254
pp/oppai-ng/test/gentest.py
Normal file
254
pp/oppai-ng/test/gentest.py
Normal file
@@ -0,0 +1,254 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
import json
|
||||
import traceback
|
||||
import argparse
|
||||
import hashlib
|
||||
|
||||
if sys.version_info[0] < 3:
|
||||
# hack to force utf-8
|
||||
reload(sys)
|
||||
sys.setdefaultencoding('utf-8')
|
||||
|
||||
try:
|
||||
import httplib
|
||||
except ImportError:
|
||||
import http.client as httplib
|
||||
|
||||
try:
|
||||
import urllib
|
||||
except ImportError:
|
||||
import urllib.parse as urllib
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description = (
|
||||
'generates the oppai test suite. outputs c++ code to ' +
|
||||
'stdout and the json dump to a file.'
|
||||
)
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'-key',
|
||||
default = None,
|
||||
help = (
|
||||
'osu! api key. required if -input-file is not present. ' +
|
||||
'can also be specified through the OSU_API_KEY ' +
|
||||
'environment variable'
|
||||
)
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'-output-file',
|
||||
default = 'test_suite.json',
|
||||
help = 'dumps json to this file'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'-input-file',
|
||||
default = None,
|
||||
help = (
|
||||
'loads test suite from this json file instead of '
|
||||
'fetching it from osu api. if set to "-", json will be '
|
||||
'read from standard input'
|
||||
)
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.key == None and 'OSU_API_KEY' in os.environ:
|
||||
args.key = os.environ['OSU_API_KEY']
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
osu_treset = time.time() + 60
|
||||
osu_ncalls = 0
|
||||
|
||||
def osu_get(conn, endpoint, paramsdict=None):
|
||||
# GETs /api/endpoint?paramsdict&k=args.key from conn
|
||||
# return json object, exits process on api errors
|
||||
global osu_treset, osu_ncalls, args
|
||||
|
||||
sys.stderr.write('%s %s\n' % (endpoint, str(paramsdict)))
|
||||
|
||||
paramsdict['k'] = args.key
|
||||
path = '/api/%s?%s' % (endpoint, urllib.urlencode(paramsdict))
|
||||
|
||||
while True:
|
||||
while True:
|
||||
if time.time() >= osu_treset:
|
||||
osu_ncalls = 0
|
||||
osu_treset = time.time() + 60
|
||||
sys.stderr.write('\napi ready\n')
|
||||
|
||||
if osu_ncalls < 60:
|
||||
break
|
||||
else:
|
||||
sys.stderr.write('waiting for api cooldown...\r')
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
try:
|
||||
conn.request('GET', path)
|
||||
osu_ncalls += 1
|
||||
r = conn.getresponse()
|
||||
|
||||
raw = ''
|
||||
|
||||
while True:
|
||||
try:
|
||||
raw += r.read()
|
||||
break
|
||||
except httplib.IncompleteRead as e:
|
||||
raw += e.partial
|
||||
|
||||
j = json.loads(raw)
|
||||
|
||||
if 'error' in j:
|
||||
sys.stderr.write('%s\n' % j['error'])
|
||||
sys.exit(1)
|
||||
|
||||
return j
|
||||
|
||||
except (httplib.HTTPException, ValueError) as e:
|
||||
sys.stderr.write('%s\n' % (traceback.format_exc()))
|
||||
|
||||
try:
|
||||
# prevents exceptions on next request if the
|
||||
# response wasn't previously read due to errors
|
||||
conn.getresponse().read()
|
||||
|
||||
except httplib.HTTPException:
|
||||
pass
|
||||
|
||||
time.sleep(5)
|
||||
|
||||
|
||||
def gen_modstr(bitmask):
|
||||
# generates c++ code for a mod combination's bitmask
|
||||
mods = []
|
||||
|
||||
allmods = {
|
||||
(1<< 0, 'nf'), (1<< 1, 'ez'), (1<< 2, 'td'), (1<< 3, 'hd'),
|
||||
(1<< 4, 'hr'), (1<< 6, 'dt'), (1<< 8, 'ht'),
|
||||
(1<< 9, 'nc'), (1<<10, 'fl'), (1<<12, 'so')
|
||||
}
|
||||
|
||||
for bit, string in allmods:
|
||||
if bitmask & bit != 0:
|
||||
mods.append(string)
|
||||
|
||||
if len(mods) == 0:
|
||||
return 'nomod'
|
||||
|
||||
return ' | '.join(mods)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
if args.key == None:
|
||||
sys.stderr.write(
|
||||
'please set OSU_API_KEY or pass it as a parameter\n'
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
scores = []
|
||||
|
||||
if args.input_file == None:
|
||||
# fetch a fresh test suite from osu api
|
||||
top_players = [
|
||||
124493, 4787150, 2558286, 1777162, 2831793, 50265
|
||||
]
|
||||
|
||||
osu = httplib.HTTPSConnection('osu.ppy.sh')
|
||||
|
||||
for u in top_players:
|
||||
params = { 'u': u, 'limit': 100, 'type': 'id' }
|
||||
scores += osu_get(osu, 'get_user_best', params)
|
||||
|
||||
params = { 'm': 0, 'since': '2015-11-26' }
|
||||
maps = osu_get(osu, 'get_beatmaps', params)
|
||||
|
||||
for m in maps:
|
||||
params = { 'b': m['beatmap_id'] }
|
||||
map_scores = osu_get(osu, 'get_scores', params)
|
||||
|
||||
if len(map_scores) == 0:
|
||||
sys.stderr.write('W: map has no scores???\n')
|
||||
continue
|
||||
|
||||
# note: api also returns qualified and loved, so ignore
|
||||
# maps that don't have pp in rankings
|
||||
if not 'pp' in map_scores[0]:
|
||||
sys.stderr.write('W: ignoring loved/qualified map\n')
|
||||
continue
|
||||
|
||||
for s in map_scores:
|
||||
s['beatmap_id'] = m['beatmap_id']
|
||||
|
||||
scores += map_scores
|
||||
|
||||
|
||||
with open(args.output_file, 'w+') as f:
|
||||
f.write(json.dumps(scores))
|
||||
|
||||
else:
|
||||
# load existing test suite from json file
|
||||
with open(args.input_file, 'r') as f:
|
||||
scores = json.loads(f.read())
|
||||
|
||||
|
||||
print('/* this code was automatically generated by gentest.py */')
|
||||
print('')
|
||||
|
||||
# make code a little nicer by shortening mods
|
||||
allmods = {
|
||||
'nf', 'ez', 'td', 'hd', 'hr', 'dt', 'ht', 'nc', 'fl', 'so', 'nomod'
|
||||
}
|
||||
|
||||
for mod in allmods:
|
||||
print('#define %s MODS_%s' % (mod, mod.upper()))
|
||||
|
||||
print('''
|
||||
struct score
|
||||
{
|
||||
uint32_t id;
|
||||
uint16_t max_combo;
|
||||
uint16_t n300, n100, n50, nmiss;
|
||||
uint32_t mods;
|
||||
double pp;
|
||||
};
|
||||
|
||||
struct score const suite[] =
|
||||
{''')
|
||||
|
||||
seen_hashes = []
|
||||
|
||||
for s in scores:
|
||||
# why is every value returned by osu api a string?
|
||||
line = (
|
||||
' { %s, %s, %s, %s, %s, %s, %s, %s },' %
|
||||
(
|
||||
s['beatmap_id'], s['maxcombo'], s['count300'],
|
||||
s['count100'], s['count50'], s['countmiss'],
|
||||
gen_modstr(int(s['enabled_mods'])), s['pp']
|
||||
)
|
||||
)
|
||||
|
||||
# don't include identical scores by different people
|
||||
s = hashlib.sha1(line).digest()
|
||||
if s in seen_hashes:
|
||||
continue
|
||||
|
||||
print(line)
|
||||
seen_hashes.append(s)
|
||||
|
||||
print('};\n')
|
||||
|
||||
for mod in allmods:
|
||||
print('#undef %s' % (mod))
|
||||
|
15
pp/oppai-ng/vcvarsall17.ps1
Normal file
15
pp/oppai-ng/vcvarsall17.ps1
Normal file
@@ -0,0 +1,15 @@
|
||||
# https://stackoverflow.com/questions/2124753/how-can-i-use-powershell-with-the-visual-studio-command-prompt
|
||||
|
||||
param (
|
||||
[string]$arch = "amd64"
|
||||
)
|
||||
|
||||
Push-Location "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\Common7\Tools"
|
||||
cmd /c "VsDevCmd.bat -arch=$arch&set" |
|
||||
ForEach-Object {
|
||||
if ($_ -match "=") {
|
||||
$v = $_.split("="); set-item -force -path "ENV:\$($v[0])" -value "$($v[1])"
|
||||
}
|
||||
}
|
||||
Pop-Location
|
||||
Write-Host "`nVisual Studio 2017 Command Prompt variables set." -ForegroundColor Yellow
|
Reference in New Issue
Block a user