parent
b5f35f6379
commit
1ff8e631fe
64
app/Console/Commands/MigratePlayersTable.php
Normal file
64
app/Console/Commands/MigratePlayersTable.php
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Player;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class MigratePlayersTable extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'bs:migrate-v4:players-table';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Migrate the players table for v4';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$players = Player::where('tid_skin', -1)->get();
|
||||
$count = $players->count();
|
||||
|
||||
if ($count == 0) {
|
||||
$this->info('No need to update.');
|
||||
return;
|
||||
}
|
||||
|
||||
$this->info('We are going to update your `players` table. Please wait...');
|
||||
$bar = $this->output->createProgressBar($count);
|
||||
|
||||
$players->each(function ($player) use ($bar) {
|
||||
$player->tid_skin = $player->preference == 'default'
|
||||
? $player->tid_steve
|
||||
: $player->tid_alex;
|
||||
$player->save();
|
||||
|
||||
$bar->advance();
|
||||
});
|
||||
$bar->finish();
|
||||
|
||||
$this->info("\nCongratulations! We've updated $count rows.");
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ class Kernel extends ConsoleKernel
|
|||
Commands\Inspire::class,
|
||||
Commands\KeyRandomCommand::class,
|
||||
Commands\SaltRandomCommand::class,
|
||||
Commands\MigratePlayersTable::class,
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -279,7 +279,7 @@ class AdminController extends Controller
|
|||
$isSpecifiedUser = $request->has('uid');
|
||||
|
||||
if ($isSpecifiedUser) {
|
||||
$players = Player::select(['pid', 'uid', 'player_name', 'preference', 'tid_steve', 'tid_alex', 'tid_cape', 'last_modified'])
|
||||
$players = Player::select(['pid', 'uid', 'player_name', 'tid_skin', 'tid_cape', 'last_modified'])
|
||||
->where('uid', intval($request->input('uid')))
|
||||
->get();
|
||||
} else {
|
||||
|
|
@ -289,11 +289,10 @@ class AdminController extends Controller
|
|||
$page = $request->input('page', 1);
|
||||
$perPage = $request->input('perPage', 10);
|
||||
|
||||
$players = Player::select(['pid', 'uid', 'player_name', 'preference', 'tid_steve', 'tid_alex', 'tid_cape', 'last_modified'])
|
||||
$players = Player::select(['pid', 'uid', 'player_name', 'tid_skin', 'tid_cape', 'last_modified'])
|
||||
->where('pid', 'like', '%' . $search . '%')
|
||||
->orWhere('uid', 'like', '%' . $search . '%')
|
||||
->orWhere('player_name', 'like', '%' . $search . '%')
|
||||
->orWhere('preference', 'like', '%' . $search . '%')
|
||||
->orderBy($sortField, $sortType)
|
||||
->offset(($page - 1) * $perPage)
|
||||
->limit($perPage)
|
||||
|
|
@ -425,25 +424,16 @@ class AdminController extends Controller
|
|||
}
|
||||
}
|
||||
|
||||
if ($action == "preference") {
|
||||
if ($action == "texture") {
|
||||
$this->validate($request, [
|
||||
'preference' => 'required|preference'
|
||||
]);
|
||||
|
||||
$player->setPreference($request->input('preference'));
|
||||
|
||||
return json(trans('admin.players.preference.success', ['player' => $player->player_name, 'preference' => $request->input('preference')]), 0);
|
||||
|
||||
} elseif ($action == "texture") {
|
||||
$this->validate($request, [
|
||||
'model' => 'required|model',
|
||||
'tid' => 'required|integer'
|
||||
'type' => 'required',
|
||||
'tid' => 'required|integer'
|
||||
]);
|
||||
|
||||
if (! Texture::find($request->tid) && $request->tid != 0)
|
||||
return json(trans('admin.players.textures.non-existent', ['tid' => $request->tid]), 1);
|
||||
|
||||
$player->setTexture(['tid_'.$request->model => $request->tid]);
|
||||
$player->setTexture(['tid_'.$request->type => $request->tid]);
|
||||
|
||||
return json(trans('admin.players.textures.success', ['player' => $player->player_name]), 0);
|
||||
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ class AuthController extends Controller
|
|||
$player = new Player;
|
||||
$player->uid = $user->uid;
|
||||
$player->player_name = $request->get('player_name');
|
||||
$player->preference = 'default';
|
||||
$player->tid_skin = 0;
|
||||
$player->last_modified = get_datetime_string();
|
||||
$player->save();
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ class PlayerController extends Controller
|
|||
});
|
||||
|
||||
$this->middleware([CheckPlayerExist::class, CheckPlayerOwner::class], [
|
||||
'only' => ['delete', 'rename', 'setTexture', 'clearTexture', 'setPreference']
|
||||
'only' => ['delete', 'rename', 'setTexture', 'clearTexture']
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ class PlayerController extends Controller
|
|||
{
|
||||
return Auth::user()
|
||||
->players()
|
||||
->select('pid', 'player_name', 'preference', 'tid_steve', 'tid_alex')
|
||||
->select('pid', 'player_name', 'tid_skin', 'tid_cape')
|
||||
->get();
|
||||
}
|
||||
|
||||
|
|
@ -86,7 +86,7 @@ class PlayerController extends Controller
|
|||
|
||||
$player->uid = $user->uid;
|
||||
$player->player_name = $request->input('player_name');
|
||||
$player->preference = "default";
|
||||
$player->tid_skin = 0;
|
||||
$player->last_modified = get_datetime_string();
|
||||
$player->save();
|
||||
|
||||
|
|
@ -153,24 +153,17 @@ class PlayerController extends Controller
|
|||
return json(trans('skinlib.un-existent'), 6);
|
||||
}
|
||||
|
||||
$fieldName = "tid_{$texture->type}";
|
||||
$fieldName = $texture->type == 'cape' ? 'tid_cape' : 'tid_skin';
|
||||
|
||||
$this->player->setTexture([$fieldName => $value]);
|
||||
}
|
||||
|
||||
// When user applies an alex skin to a newly added player,
|
||||
// which textures and model preference are all default value,
|
||||
// we will automatically set the player's model preference to "slim".
|
||||
if ($this->player->preference == 'default' && $this->player->tid_steve == 0 && $this->player->tid_alex != 0) {
|
||||
$this->player->setPreference('slim');
|
||||
}
|
||||
|
||||
return json(trans('user.player.set.success', ['name' => $this->player->player_name]), 0);
|
||||
}
|
||||
|
||||
public function clearTexture(Request $request)
|
||||
{
|
||||
$types = array_filter(['steve', 'alex', 'cape'], function ($type) use ($request) {
|
||||
$types = array_filter(['skin', 'cape'], function ($type) use ($request) {
|
||||
return $request->input($type);
|
||||
});
|
||||
|
||||
|
|
@ -179,15 +172,4 @@ class PlayerController extends Controller
|
|||
return json(trans('user.player.clear.success', ['name' => $this->player->player_name]), 0);
|
||||
}
|
||||
|
||||
public function setPreference(Request $request)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'preference' => 'required|preference'
|
||||
]);
|
||||
|
||||
$this->player->setPreference($request->preference);
|
||||
|
||||
return json(trans('user.player.preference.success', ['name' => $this->player->player_name, 'preference' => $request->preference]), 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ class SkinlibController extends Controller
|
|||
return json(trans('skinlib.upload.lack-score'), 1);
|
||||
}
|
||||
|
||||
$type = $t->type;
|
||||
$type = $t->type == 'cape' ? 'cape' : 'skin';
|
||||
Player::where("tid_$type", $t->tid)
|
||||
->where('uid', '<>', session('uid'))
|
||||
->get()
|
||||
|
|
|
|||
|
|
@ -70,19 +70,9 @@ class TextureController extends Controller
|
|||
return $this->texture($hash);
|
||||
}
|
||||
|
||||
public function skin($player_name, $model = "")
|
||||
public function skin($player_name)
|
||||
{
|
||||
$player = $this->getPlayerInstance($player_name);
|
||||
|
||||
$model_preference = ($player->getPreference() == "default") ? "steve" : "alex";
|
||||
$model = ($model == "") ? $model_preference : $model;
|
||||
|
||||
return $this->getBinaryTextureFromPlayer($player_name, $model);
|
||||
}
|
||||
|
||||
public function skinWithModel($model, $player_name)
|
||||
{
|
||||
return $this->skin($player_name, $model);
|
||||
return $this->getBinaryTextureFromPlayer($player_name, 'skin');
|
||||
}
|
||||
|
||||
public function cape($player_name)
|
||||
|
|
@ -95,7 +85,7 @@ class TextureController extends Controller
|
|||
*
|
||||
* @param string $player_name
|
||||
* @param string $type "steve" or "alex" or "cape".
|
||||
* @return void|Response
|
||||
* @return Response
|
||||
*/
|
||||
protected function getBinaryTextureFromPlayer($player_name, $type)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -18,17 +18,14 @@ class Player extends Model
|
|||
const CSL_API = 0;
|
||||
const USM_API = 1;
|
||||
|
||||
/**
|
||||
* Set of models.
|
||||
*/
|
||||
protected static $models = ['steve', 'alex', 'cape'];
|
||||
protected static $types = ['skin', 'cape'];
|
||||
|
||||
/**
|
||||
* Properties for Eloquent Model.
|
||||
*/
|
||||
public $primaryKey = 'pid';
|
||||
public $timestamps = false;
|
||||
protected $fillable = ['uid', 'player_name', 'preference', 'last_modified'];
|
||||
protected $fillable = ['uid', 'player_name', 'last_modified'];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
|
|
@ -38,8 +35,7 @@ class Player extends Model
|
|||
protected $casts = [
|
||||
'pid' => 'integer',
|
||||
'uid' => 'integer',
|
||||
'tid_steve' => 'integer',
|
||||
'tid_alex' => 'integer',
|
||||
'tid_skin' => 'integer',
|
||||
'tid_cape' => 'integer',
|
||||
];
|
||||
|
||||
|
|
@ -63,18 +59,27 @@ class Player extends Model
|
|||
return $this->belongsTo('App\Models\User', 'uid');
|
||||
}
|
||||
|
||||
public function getTidSkinAttribute($value)
|
||||
{
|
||||
if ($value == -1) {
|
||||
$this->tid_skin = $value = $this->preference == 'default'
|
||||
? $this->tid_steve
|
||||
: $this->tid_alex;
|
||||
$this->save();
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get specific texture of player.
|
||||
*
|
||||
* @param string $type "steve" or "alex" or "cape".
|
||||
* @param string $type "skin" or "cape".
|
||||
* @return string The sha256 hash of texture file.
|
||||
*/
|
||||
public function getTexture($type)
|
||||
{
|
||||
if ($type == "skin")
|
||||
$type = ($this->getPreference() == "default") ? "steve" : "alex";
|
||||
|
||||
if (in_array($type, self::$models)) {
|
||||
if (in_array($type, self::$types)) {
|
||||
return Texture::find($this["tid_$type"])['hash'];
|
||||
}
|
||||
|
||||
|
|
@ -89,8 +94,8 @@ class Player extends Model
|
|||
*/
|
||||
public function setTexture(Array $tids)
|
||||
{
|
||||
foreach (self::$models as $model) {
|
||||
$property = "tid_$model";
|
||||
foreach (self::$types as $type) {
|
||||
$property = "tid_$type";
|
||||
|
||||
if (isset($tids[$property])) {
|
||||
$this->$property = $tids[$property];
|
||||
|
|
@ -113,8 +118,8 @@ class Player extends Model
|
|||
*/
|
||||
public function checkForInvalidTextures()
|
||||
{
|
||||
foreach (self::$models as $model) {
|
||||
$property = "tid_$model";
|
||||
foreach (self::$types as $type) {
|
||||
$property = "tid_$type";
|
||||
|
||||
if (! Texture::find($this->$property)) {
|
||||
// reset texture
|
||||
|
|
@ -148,34 +153,6 @@ class Player extends Model
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set preferred model for the player.
|
||||
*
|
||||
* @param string $type "slim" or "default".
|
||||
* @return $this
|
||||
*/
|
||||
public function setPreference($type)
|
||||
{
|
||||
$this->update([
|
||||
'preference' => $type,
|
||||
'last_modified' => get_datetime_string()
|
||||
]);
|
||||
|
||||
event(new PlayerProfileUpdated($this));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get model preference of the player.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPreference()
|
||||
{
|
||||
return $this['preference'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename the player.
|
||||
*
|
||||
|
|
@ -244,20 +221,19 @@ class Player extends Model
|
|||
{
|
||||
$json[($api_type == self::CSL_API) ? 'username' : 'player_name'] = $this->player_name;
|
||||
|
||||
$model = $this->getPreference();
|
||||
$sec_model = ($model == 'default') ? 'slim' : 'default';
|
||||
$texture = Texture::find($this->tid_skin);
|
||||
$model = empty($texture) ? 'default' : ($texture->type === 'steve' ? 'default' : 'slim');
|
||||
|
||||
if ($api_type == self::USM_API) {
|
||||
$json['last_update'] = strtotime($this->last_modified);
|
||||
$json['model_preference'] = [$model, $sec_model];
|
||||
$json['model_preference'] = [$model];
|
||||
}
|
||||
|
||||
if ($this->getTexture('steve') || $this->getTexture('alex')) {
|
||||
// Skins dict order by preference model
|
||||
$json['skins'][$model] = $this->getTexture($model == "default" ? "steve" : "alex");
|
||||
$json['skins'][$sec_model] = $this->getTexture($sec_model == "default" ? "steve" : "alex");
|
||||
$skinHash = $this->getTexture('skin');
|
||||
if ($model == 'slim') {
|
||||
$json['skins']['slim'] = $skinHash;
|
||||
}
|
||||
|
||||
$json['skins']['default'] = $skinHash;
|
||||
$json['cape'] = $this->getTexture('cape');
|
||||
|
||||
return json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
||||
|
|
|
|||
|
|
@ -46,14 +46,6 @@ class ValidatorExtendServiceProvider extends ServiceProvider
|
|||
return preg_match($regexp, $value);
|
||||
});
|
||||
|
||||
Validator::extend('preference', function ($a, $value, $p, $v) {
|
||||
return preg_match('/^(default|slim)$/', $value);
|
||||
});
|
||||
|
||||
Validator::extend('model', function ($a, $value, $p, $v) {
|
||||
return preg_match('/^(steve|alex|cape)$/', $value);
|
||||
});
|
||||
|
||||
$this->registerExpiredRules();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@
|
|||
"devitek/yaml-translation": "^4.1.0",
|
||||
"composer/semver": "^1.4",
|
||||
"mews/captcha": "^2.2",
|
||||
"guzzlehttp/guzzle": "^6.3"
|
||||
"guzzlehttp/guzzle": "^6.3",
|
||||
"doctrine/dbal": "^2.9"
|
||||
},
|
||||
"require-dev": {
|
||||
"fzaninotto/faker": "~1.4",
|
||||
|
|
|
|||
233
composer.lock
generated
233
composer.lock
generated
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "9dffd7e330ca90a80760f9e44a3c9c50",
|
||||
"content-hash": "425b8e682534d97b800252cf1ec95152",
|
||||
"packages": [
|
||||
{
|
||||
"name": "composer/semver",
|
||||
|
|
@ -114,6 +114,237 @@
|
|||
"description": "Add YAML file support to Laravel TranslationServiceProvider",
|
||||
"time": "2017-09-28T12:37:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/cache",
|
||||
"version": "v1.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/cache.git",
|
||||
"reference": "d768d58baee9a4862ca783840eca1b9add7a7f57"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/cache/zipball/d768d58baee9a4862ca783840eca1b9add7a7f57",
|
||||
"reference": "d768d58baee9a4862ca783840eca1b9add7a7f57",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "~7.1"
|
||||
},
|
||||
"conflict": {
|
||||
"doctrine/common": ">2.2,<2.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"alcaeus/mongo-php-adapter": "^1.1",
|
||||
"doctrine/coding-standard": "^4.0",
|
||||
"mongodb/mongodb": "^1.1",
|
||||
"phpunit/phpunit": "^7.0",
|
||||
"predis/predis": "~1.0"
|
||||
},
|
||||
"suggest": {
|
||||
"alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.8.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Roman Borschel",
|
||||
"email": "roman@code-factory.org"
|
||||
},
|
||||
{
|
||||
"name": "Benjamin Eberlei",
|
||||
"email": "kontakt@beberlei.de"
|
||||
},
|
||||
{
|
||||
"name": "Guilherme Blanco",
|
||||
"email": "guilhermeblanco@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Jonathan Wage",
|
||||
"email": "jonwage@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Johannes Schmitt",
|
||||
"email": "schmittjoh@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Caching library offering an object-oriented API for many cache backends",
|
||||
"homepage": "https://www.doctrine-project.org",
|
||||
"keywords": [
|
||||
"cache",
|
||||
"caching"
|
||||
],
|
||||
"time": "2018-08-21T18:01:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/dbal",
|
||||
"version": "v2.9.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/dbal.git",
|
||||
"reference": "22800bd651c1d8d2a9719e2a3dc46d5108ebfcc9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/dbal/zipball/22800bd651c1d8d2a9719e2a3dc46d5108ebfcc9",
|
||||
"reference": "22800bd651c1d8d2a9719e2a3dc46d5108ebfcc9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/cache": "^1.0",
|
||||
"doctrine/event-manager": "^1.0",
|
||||
"ext-pdo": "*",
|
||||
"php": "^7.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "^5.0",
|
||||
"jetbrains/phpstorm-stubs": "^2018.1.2",
|
||||
"phpstan/phpstan": "^0.10.1",
|
||||
"phpunit/phpunit": "^7.4",
|
||||
"symfony/console": "^2.0.5|^3.0|^4.0",
|
||||
"symfony/phpunit-bridge": "^3.4.5|^4.0.5"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/console": "For helpful console commands such as SQL execution and import of files."
|
||||
},
|
||||
"bin": [
|
||||
"bin/doctrine-dbal"
|
||||
],
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.9.x-dev",
|
||||
"dev-develop": "3.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Doctrine\\DBAL\\": "lib/Doctrine/DBAL"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Roman Borschel",
|
||||
"email": "roman@code-factory.org"
|
||||
},
|
||||
{
|
||||
"name": "Benjamin Eberlei",
|
||||
"email": "kontakt@beberlei.de"
|
||||
},
|
||||
{
|
||||
"name": "Guilherme Blanco",
|
||||
"email": "guilhermeblanco@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Jonathan Wage",
|
||||
"email": "jonwage@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.",
|
||||
"homepage": "https://www.doctrine-project.org/projects/dbal.html",
|
||||
"keywords": [
|
||||
"abstraction",
|
||||
"database",
|
||||
"dbal",
|
||||
"mysql",
|
||||
"persistence",
|
||||
"pgsql",
|
||||
"php",
|
||||
"queryobject"
|
||||
],
|
||||
"time": "2018-12-31T03:27:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/event-manager",
|
||||
"version": "v1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/event-manager.git",
|
||||
"reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/event-manager/zipball/a520bc093a0170feeb6b14e9d83f3a14452e64b3",
|
||||
"reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1"
|
||||
},
|
||||
"conflict": {
|
||||
"doctrine/common": "<2.9@dev"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "^4.0",
|
||||
"phpunit/phpunit": "^7.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Doctrine\\Common\\": "lib/Doctrine/Common"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Roman Borschel",
|
||||
"email": "roman@code-factory.org"
|
||||
},
|
||||
{
|
||||
"name": "Benjamin Eberlei",
|
||||
"email": "kontakt@beberlei.de"
|
||||
},
|
||||
{
|
||||
"name": "Guilherme Blanco",
|
||||
"email": "guilhermeblanco@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Jonathan Wage",
|
||||
"email": "jonwage@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Johannes Schmitt",
|
||||
"email": "schmittjoh@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Marco Pivetta",
|
||||
"email": "ocramius@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Doctrine Event Manager component",
|
||||
"homepage": "https://www.doctrine-project.org/projects/event-manager.html",
|
||||
"keywords": [
|
||||
"event",
|
||||
"eventdispatcher",
|
||||
"eventmanager"
|
||||
],
|
||||
"time": "2018-06-11T11:59:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/inflector",
|
||||
"version": "v1.1.0",
|
||||
|
|
|
|||
|
|
@ -6,16 +6,7 @@ $factory->define(Player::class, function (Faker\Generator $faker) {
|
|||
return [
|
||||
'uid' => factory(App\Models\User::class)->create()->uid,
|
||||
'player_name' => $faker->firstName,
|
||||
'preference' => 'default',
|
||||
'last_modified' => $faker->dateTime
|
||||
];
|
||||
});
|
||||
|
||||
$factory->defineAs(Player::class, 'slim', function (Faker\Generator $faker) {
|
||||
return [
|
||||
'uid' => factory(App\Models\User::class)->create()->uid,
|
||||
'player_name' => $faker->firstName,
|
||||
'preference' => 'slim',
|
||||
'tid_skin' => 0,
|
||||
'last_modified' => $faker->dateTime
|
||||
];
|
||||
});
|
||||
|
|
|
|||
|
|
@ -26,16 +26,7 @@ class AddRememberTokenToUsersTable extends Migration
|
|||
public function down()
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
if (config('database.default') == 'sqlite') {
|
||||
// Dropping columns from a SQLite database requires `doctrine/dbal` dependency.
|
||||
// However, we won't install it because it's too hard to specify the version of
|
||||
// all the new dependencies exactly to make them support PHP ^5.5.9. Damn it.
|
||||
return;
|
||||
}
|
||||
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->dropColumn('remember_token');
|
||||
});
|
||||
$table->dropColumn('remember_token');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
34
database/migrations/2019_03_01_131420_add_tid_skin.php
Normal file
34
database/migrations/2019_03_01_131420_add_tid_skin.php
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddTidSkin extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('players', function (Blueprint $table) {
|
||||
$table->integer('tid_skin')->default(-1);
|
||||
$table->string('preference', 10)->nullable()->change();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('players', function (Blueprint $table) {
|
||||
$table->dropColumn('tid_skin');
|
||||
$table->string('preference', 10)->nullable(false)->change();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -31,24 +31,12 @@
|
|||
<i class="fas fa-edit btn-edit"></i>
|
||||
</a>
|
||||
</span>
|
||||
<span v-else-if="props.column.field === 'preference'">
|
||||
{{ props.formattedRow[props.column.field] }}
|
||||
<a @click="togglePreference(props.row)" :title="$t('admin.changePreference')" data-test="preference">
|
||||
<i class="fas fa-edit btn-edit"></i>
|
||||
</a>
|
||||
</span>
|
||||
<span v-else-if="props.column.field === 'preview'">
|
||||
<a
|
||||
v-if="props.row.tid_steve"
|
||||
:href="`${baseUrl}/skinlib/show/${props.row.tid_steve}`"
|
||||
v-if="props.row.tid_skin"
|
||||
:href="`${baseUrl}/skinlib/show/${props.row.tid_skin}`"
|
||||
>
|
||||
<img :src="`${baseUrl}/preview/64/${props.row.tid_steve}.png`" width="64">
|
||||
</a>
|
||||
<a
|
||||
v-if="props.row.tid_alex"
|
||||
:href="`${baseUrl}/skinlib/show/${props.row.tid_alex}`"
|
||||
>
|
||||
<img :src="`${baseUrl}/preview/64/${props.row.tid_alex}.png`" width="64">
|
||||
<img :src="`${baseUrl}/preview/64/${props.row.tid_skin}.png`" width="64">
|
||||
</a>
|
||||
<a
|
||||
v-if="props.row.tid_cape"
|
||||
|
|
@ -95,9 +83,8 @@
|
|||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label v-t="'admin.textureType'" />
|
||||
<select class="form-control" v-model="textureChanges.model">
|
||||
<option value="steve">Steve</option>
|
||||
<option value="alex">Alex</option>
|
||||
<select class="form-control" v-model="textureChanges.type">
|
||||
<option value="skin" v-t="'general.skin'"></option>
|
||||
<option value="cape" v-t="'general.cape'"></option>
|
||||
</select>
|
||||
</div>
|
||||
|
|
@ -150,7 +137,6 @@ export default {
|
|||
{ field: 'pid', label: 'PID', type: 'number' },
|
||||
{ field: 'player_name', label: this.$t('general.player.player-name') },
|
||||
{ field: 'uid', label: this.$t('general.player.owner'), type: 'number' },
|
||||
{ field: 'preference', label: this.$t('general.player.preference'), globalSearchDisabled: true },
|
||||
{ field: 'preview', label: this.$t('general.player.previews'), globalSearchDisabled: true, sortable: false },
|
||||
{ field: 'last_modified', label: this.$t('general.player.last-modified') },
|
||||
{ field: 'operations', label: this.$t('admin.operationsTitle'), globalSearchDisabled: true, sortable: false },
|
||||
|
|
@ -178,7 +164,7 @@ export default {
|
|||
},
|
||||
textureChanges: {
|
||||
originalIndex: -1,
|
||||
model: 'steve',
|
||||
type: 'skin',
|
||||
tid: '',
|
||||
}
|
||||
};
|
||||
|
|
@ -214,14 +200,14 @@ export default {
|
|||
},
|
||||
async changeTexture() {
|
||||
const player = this.players[this.textureChanges.originalIndex];
|
||||
const { model, tid } = this.textureChanges;
|
||||
const { type, tid } = this.textureChanges;
|
||||
|
||||
const { errno, msg } = await this.$http.post(
|
||||
'/admin/players?action=texture',
|
||||
{ pid: player.pid, model, tid }
|
||||
{ pid: player.pid, type, tid }
|
||||
);
|
||||
if (errno === 0) {
|
||||
player[`tid_${model}`] = tid;
|
||||
player[`tid_${type}`] = tid;
|
||||
toastr.success(msg);
|
||||
$('.modal').modal('hide');
|
||||
} else {
|
||||
|
|
@ -250,19 +236,6 @@ export default {
|
|||
toastr.warning(msg);
|
||||
}
|
||||
},
|
||||
async togglePreference(player) {
|
||||
const preference = player.preference === 'default' ? 'slim' : 'default';
|
||||
const { errno, msg } = await this.$http.post(
|
||||
'/admin/players?action=preference',
|
||||
{ pid: player.pid, preference }
|
||||
);
|
||||
if (errno === 0) {
|
||||
player.preference = preference;
|
||||
toastr.success(msg);
|
||||
} else {
|
||||
toastr.warning(msg);
|
||||
}
|
||||
},
|
||||
async changeOwner(player) {
|
||||
const { dismiss, value } = await swal({
|
||||
text: this.$t('admin.changePlayerOwner'),
|
||||
|
|
|
|||
|
|
@ -266,8 +266,7 @@ export default {
|
|||
this.loadCloset(page);
|
||||
},
|
||||
avatarUrl(player) {
|
||||
const tid = player.preference === 'default' ? player.tid_steve : player.tid_alex;
|
||||
return `${blessing.base_url}/avatar/35/${tid}`;
|
||||
return `${blessing.base_url}/avatar/35/${player.tid_skin}`;
|
||||
},
|
||||
async selectTexture(tid) {
|
||||
const { type, hash } = await this.$http.get(`/skinlib/info/${tid}`);
|
||||
|
|
|
|||
|
|
@ -9,16 +9,6 @@
|
|||
<tr>
|
||||
<th>PID</th>
|
||||
<th v-t="'general.player.player-name'"></th>
|
||||
<th>
|
||||
{{ $t('user.player.preference.title') }}
|
||||
<i
|
||||
class="fas fa-question-circle"
|
||||
:title="$t('user.player.preference.description')"
|
||||
data-toggle="tooltip"
|
||||
data-placement="right"
|
||||
></i>
|
||||
</th>
|
||||
<th v-t="'user.player.edit'"></th>
|
||||
<th v-t="'user.player.operation'"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
|
@ -33,20 +23,12 @@
|
|||
>
|
||||
<td class="pid">{{ player.pid }}</td>
|
||||
<td class="player-name">{{ player.player_name }}</td>
|
||||
<td>
|
||||
<select class="form-control" @change="togglePreference(player)">
|
||||
<option value="default" :selected="player.preference === 'default'">Default (Steve)</option>
|
||||
<option value="slim" :selected="player.preference === 'slim'">Slim (Alex)</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<a
|
||||
class="btn btn-default btn-sm"
|
||||
@click="changeName(player)"
|
||||
v-t="'user.player.edit-pname'"
|
||||
></a>
|
||||
</td>
|
||||
<td>
|
||||
<a
|
||||
class="btn btn-warning btn-sm"
|
||||
data-toggle="modal"
|
||||
|
|
@ -104,36 +86,25 @@
|
|||
<div class="box-body">
|
||||
<div id="preview-2d">
|
||||
<p>
|
||||
{{ $t('user.player.textures.steve') }}
|
||||
<a v-if="preview2d.steve" :href="`${baseUrl}/skinlib/show/${preview2d.steve}`">
|
||||
{{ $t('general.skin') }}
|
||||
<a v-if="preview2d.skin" :href="`${baseUrl}/skinlib/show/${preview2d.skin}`">
|
||||
<img
|
||||
class="skin2d"
|
||||
:src="`${baseUrl}/preview/64/${preview2d.steve}.png`"
|
||||
/>
|
||||
</a>
|
||||
<span v-else class="skin2d" v-t="'user.player.textures.empty'"></span>
|
||||
<span v-else class="skin2d" v-t="'user.player.texture-empty'"></span>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
{{ $t('user.player.textures.alex') }}
|
||||
<a v-if="preview2d.alex" :href="`${baseUrl}/skinlib/show/${preview2d.alex}`">
|
||||
<img
|
||||
class="skin2d"
|
||||
:src="`${baseUrl}/preview/64/${preview2d.alex}.png`"
|
||||
/>
|
||||
</a>
|
||||
<span v-else class="skin2d" v-t="'user.player.textures.empty'"></span>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
{{ $t('user.player.textures.cape') }}
|
||||
{{ $t('general.cape') }}
|
||||
<a v-if="preview2d.cape" :href="`${baseUrl}/skinlib/show/${preview2d.cape}`">
|
||||
<img
|
||||
class="skin2d"
|
||||
:src="`${baseUrl}/preview/64/${preview2d.cape}.png`"
|
||||
/>
|
||||
</a>
|
||||
<span v-else class="skin2d" v-t="'user.player.textures.empty'"></span>
|
||||
<span v-else class="skin2d" v-t="'user.player.texture-empty'"></span>
|
||||
</p>
|
||||
</div>
|
||||
</div><!-- /.box-body -->
|
||||
|
|
@ -220,11 +191,7 @@
|
|||
</div>
|
||||
<div class="modal-body">
|
||||
<label class="form-group">
|
||||
<input type="checkbox" v-model="clear.steve"> Default (Steve)
|
||||
</label>
|
||||
<br>
|
||||
<label class="form-group">
|
||||
<input type="checkbox" v-model="clear.alex"> Slim (Alex)
|
||||
<input type="checkbox" v-model="clear.skin"> {{ $t('general.skin') }}
|
||||
</label>
|
||||
<br>
|
||||
<label class="form-group">
|
||||
|
|
@ -247,7 +214,6 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import SkinAlex from '../../images/textures/alex.png';
|
||||
import { swal } from '../../js/notify';
|
||||
import toastr from 'toastr';
|
||||
|
||||
|
|
@ -269,14 +235,12 @@ export default {
|
|||
skinUrl: '',
|
||||
capeUrl: '',
|
||||
preview2d: {
|
||||
steve: 0,
|
||||
alex: 0,
|
||||
skin: 0,
|
||||
cape: 0
|
||||
},
|
||||
newPlayer: '',
|
||||
clear: {
|
||||
steve: false,
|
||||
alex: false,
|
||||
skin: false,
|
||||
cape: false
|
||||
},
|
||||
playerNameRule: blessing.extra.rule,
|
||||
|
|
@ -296,24 +260,14 @@ export default {
|
|||
async preview(player) {
|
||||
this.selected = player.pid;
|
||||
|
||||
this.preview2d.steve = player.tid_steve;
|
||||
this.preview2d.alex = player.tid_alex;
|
||||
this.preview2d.skin = player.tid_skin;
|
||||
this.preview2d.cape = player.tid_cape;
|
||||
|
||||
if (player.preference === 'default') {
|
||||
if (player.tid_steve) {
|
||||
const steve = await this.$http.get(`/skinlib/info/${player.tid_steve}`);
|
||||
this.skinUrl = `${this.baseUrl}/textures/${steve.hash}`;
|
||||
} else {
|
||||
this.skinUrl = '';
|
||||
}
|
||||
if (player.tid_skin) {
|
||||
const skin = await this.$http.get(`/skinlib/info/${player.tid_skin}`);
|
||||
this.skinUrl = `${this.baseUrl}/textures/${skin.hash}`;
|
||||
} else {
|
||||
if (player.tid_alex) {
|
||||
const alex = await this.$http.get(`/skinlib/info/${player.tid_alex}`);
|
||||
this.skinUrl = `${this.baseUrl}/textures/${alex.hash}`;
|
||||
} else {
|
||||
this.skinUrl = SkinAlex;
|
||||
}
|
||||
this.skinUrl = '';
|
||||
}
|
||||
if (player.tid_cape) {
|
||||
const cape = await this.$http.get(`/skinlib/info/${player.tid_cape}`);
|
||||
|
|
@ -322,19 +276,6 @@ export default {
|
|||
this.capeUrl = '';
|
||||
}
|
||||
},
|
||||
async togglePreference(player) {
|
||||
const preference = player.preference === 'default' ? 'slim' : 'default';
|
||||
const { errno, msg } = await this.$http.post(
|
||||
'/user/player/preference',
|
||||
{ pid: player.pid, preference }
|
||||
);
|
||||
if (errno === 0) {
|
||||
player.preference = preference;
|
||||
toastr.success(msg);
|
||||
} else {
|
||||
toastr.warning(msg);
|
||||
}
|
||||
},
|
||||
async changeName(player) {
|
||||
const { dismiss, value } = await swal({
|
||||
title: this.$t('user.changePlayerName'),
|
||||
|
|
@ -432,10 +373,6 @@ export default {
|
|||
cursor: pointer;
|
||||
border-bottom: 1px solid #f4f4f4;
|
||||
|
||||
#preference {
|
||||
height: 31px;
|
||||
}
|
||||
|
||||
.pid, .player-name {
|
||||
padding-top: 13px;
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 3.3 KiB |
|
|
@ -49,7 +49,7 @@ test('update tables', async () => {
|
|||
test('change texture', async () => {
|
||||
window.$ = jest.fn(() => ({ modal() {} }));
|
||||
Vue.prototype.$http.get.mockResolvedValue({ data: [
|
||||
{ pid: 1, tid_steve: 0 }
|
||||
{ pid: 1, tid_skin: 0 }
|
||||
] });
|
||||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ errno: 1, msg: '1' })
|
||||
|
|
@ -66,7 +66,7 @@ test('change texture', async () => {
|
|||
await wrapper.vm.$nextTick();
|
||||
expect(Vue.prototype.$http.post).toBeCalledWith(
|
||||
'/admin/players?action=texture',
|
||||
{ pid: 1, model: 'steve', tid: 5 }
|
||||
{ pid: 1, tid: 5, type: 'skin' }
|
||||
);
|
||||
|
||||
button.trigger('click');
|
||||
|
|
@ -108,33 +108,6 @@ test('change player name', async () => {
|
|||
expect(wrapper.text()).toContain('new');
|
||||
});
|
||||
|
||||
test('toggle preference', async () => {
|
||||
Vue.prototype.$http.get.mockResolvedValue({ data: [
|
||||
{ pid: 1, preference: 'default' }
|
||||
] });
|
||||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ errno: 1, msg: '1' })
|
||||
.mockResolvedValue({ errno: 0, msg: '0' });
|
||||
|
||||
const wrapper = mount(Players);
|
||||
await wrapper.vm.$nextTick();
|
||||
const button = wrapper.find('[data-test="preference"]');
|
||||
|
||||
button.trigger('click');
|
||||
expect(Vue.prototype.$http.post).toBeCalledWith(
|
||||
'/admin/players?action=preference',
|
||||
{ pid: 1, preference: 'slim' }
|
||||
);
|
||||
|
||||
button.trigger('click');
|
||||
await flushPromises();
|
||||
expect(wrapper.text()).toContain('slim');
|
||||
|
||||
button.trigger('click');
|
||||
await flushPromises();
|
||||
expect(wrapper.text()).toContain('default');
|
||||
});
|
||||
|
||||
test('change owner', async () => {
|
||||
Vue.prototype.$http.get.mockResolvedValue({ data: [
|
||||
{ pid: 1, uid: 2 }
|
||||
|
|
|
|||
|
|
@ -152,8 +152,7 @@ test('compute avatar URL', () => {
|
|||
Vue.prototype.$http.get.mockResolvedValue({});
|
||||
const wrapper = mount(Closet);
|
||||
const { avatarUrl } = wrapper.vm;
|
||||
expect(avatarUrl({ preference: 'default', tid_steve: 1 })).toBe('/avatar/35/1');
|
||||
expect(avatarUrl({ preference: 'slim', tid_alex: 1 })).toBe('/avatar/35/1');
|
||||
expect(avatarUrl({ tid_skin: 1 })).toBe('/avatar/35/1');
|
||||
});
|
||||
|
||||
test('select texture', async () => {
|
||||
|
|
@ -191,7 +190,7 @@ test('apply texture', async () => {
|
|||
.mockResolvedValueOnce({})
|
||||
.mockResolvedValueOnce([])
|
||||
.mockResolvedValueOnce([
|
||||
{ pid: 1, player_name: 'name', preference: 'default', tid_steve: 10 }
|
||||
{ pid: 1, player_name: 'name', tid_skin: 10 }
|
||||
]);
|
||||
|
||||
const wrapper = mount(Closet);
|
||||
|
|
|
|||
|
|
@ -28,10 +28,9 @@ test('fetch players data before mount', () => {
|
|||
test('click to preview player', async () => {
|
||||
Vue.prototype.$http.get
|
||||
.mockResolvedValueOnce([
|
||||
{ pid: 1, preference: 'default', tid_steve: 1, tid_alex: 2, tid_cape: 3 },
|
||||
{ pid: 2, preference: 'default', tid_steve: 0, tid_alex: 2, tid_cape: 0 },
|
||||
{ pid: 3, preference: 'slim', tid_steve: 1, tid_alex: 2, tid_cape: 0 },
|
||||
{ pid: 4, preference: 'slim', tid_steve: 0, tid_alex: 0, tid_cape: 0 },
|
||||
{ pid: 1, tid_skin: 1, tid_cape: 3 },
|
||||
{ pid: 2, tid_skin: 0, tid_cape: 0 },
|
||||
{ pid: 3, tid_skin: 2, tid_cape: 0 },
|
||||
])
|
||||
.mockResolvedValueOnce({ hash: 'a' })
|
||||
.mockResolvedValueOnce({ hash: 'b' })
|
||||
|
|
@ -51,35 +50,6 @@ test('click to preview player', async () => {
|
|||
wrapper.find('tbody > tr:nth-child(3)').trigger('click');
|
||||
await flushPromises();
|
||||
expect(Vue.prototype.$http.get).toBeCalledWith('/skinlib/info/2');
|
||||
|
||||
wrapper.find('tbody > tr:nth-child(4)').trigger('click');
|
||||
await flushPromises();
|
||||
});
|
||||
|
||||
test('toggle preference', async () => {
|
||||
Vue.prototype.$http.get
|
||||
.mockResolvedValueOnce([
|
||||
{ pid: 1, preference: 'default' },
|
||||
{ pid: 2, preference: 'slim' }
|
||||
]);
|
||||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ errno: 1 })
|
||||
.mockResolvedValue({ errno: 0 });
|
||||
const wrapper = mount(Players);
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
wrapper.findAll('select').at(0).trigger('change');
|
||||
expect(Vue.prototype.$http.post).toBeCalledWith(
|
||||
'/user/player/preference',
|
||||
{ pid: 1, preference: 'slim' }
|
||||
);
|
||||
|
||||
wrapper.findAll('select').at(1).trigger('change');
|
||||
await flushPromises();
|
||||
expect(Vue.prototype.$http.post).toBeCalledWith(
|
||||
'/user/player/preference',
|
||||
{ pid: 2, preference: 'default' }
|
||||
);
|
||||
});
|
||||
|
||||
test('change player name', async () => {
|
||||
|
|
@ -167,7 +137,7 @@ test('toggle preview mode', () => {
|
|||
Vue.prototype.$http.get.mockResolvedValueOnce([]);
|
||||
const wrapper = mount(Players);
|
||||
wrapper.find('[data-test="to2d"]').trigger('click');
|
||||
expect(wrapper.text()).toContain('user.player.textures.empty');
|
||||
expect(wrapper.text()).toContain('user.player.texture-empty');
|
||||
});
|
||||
|
||||
test('add player', async () => {
|
||||
|
|
@ -197,7 +167,7 @@ test('add player', async () => {
|
|||
test('clear texture', async () => {
|
||||
window.$ = jest.fn(() => ({ modal() {} }));
|
||||
Vue.prototype.$http.get.mockResolvedValueOnce([
|
||||
{ pid: 1, tid_steve: 1, tid_alex: 0, tid_cape: 0 }
|
||||
{ pid: 1, tid_skin: 1, tid_cape: 0 }
|
||||
]);
|
||||
Vue.prototype.$http.post
|
||||
.mockResolvedValueOnce({ errno: 1 })
|
||||
|
|
@ -214,7 +184,7 @@ test('clear texture', async () => {
|
|||
button.trigger('click');
|
||||
expect(Vue.prototype.$http.post).toBeCalledWith(
|
||||
'/user/player/texture/clear',
|
||||
{ pid: 1, steve: true, alex: false, cape: false }
|
||||
{ pid: 1, skin: true, cape: false }
|
||||
);
|
||||
|
||||
button.trigger('click');
|
||||
|
|
|
|||
|
|
@ -61,8 +61,6 @@ players:
|
|||
no-permission: You have no permission to operate this player.
|
||||
operations:
|
||||
title: Operations
|
||||
preference:
|
||||
success: The preference of player ":player" has been changed to :preference
|
||||
textures:
|
||||
change: Change Textures
|
||||
non-existent: No such texture tid.:tid
|
||||
|
|
|
|||
|
|
@ -198,11 +198,7 @@ user:
|
|||
add-player: Add new player
|
||||
login-notice: Now you can log in with player names you owned instead email address.
|
||||
player-info: Information <small>(click player name to show preview)</small>
|
||||
textures:
|
||||
steve: Steve Model:
|
||||
alex: Alex Model:
|
||||
cape: Cape:
|
||||
empty: Nothing
|
||||
texture-empty: Nothing
|
||||
pname-rule: Could only contain letters, numbers and dashes.
|
||||
pname-rule-chinese: Could only contain chinese characters, letters, numbers and dashes.
|
||||
player-name-rule:
|
||||
|
|
@ -210,9 +206,6 @@ user:
|
|||
cjk: Player name may contains letters, numbers, underscores and CJK Unified Ideographs.
|
||||
custom: Custom player name rules are applied on this site. Please contact admins for further information.
|
||||
player-name-length: The player name should be at least :min characters and not greater than :max characters.
|
||||
preference:
|
||||
title: Preference
|
||||
description: Default stands for the Steve model with 4-pixel width arms, and Slim for the Alex model with 3-pixel width arms.
|
||||
verification:
|
||||
title: Verify Your Account
|
||||
message: You must verify your email address before using the skin hosting service. Haven't received the email?
|
||||
|
|
@ -255,7 +248,6 @@ admin:
|
|||
changePlayerTexture: 'Change textures of :player'
|
||||
changeTexture: Change Textures
|
||||
changePlayerName: Change Player Name
|
||||
changePreference: Toggle Preference
|
||||
changeOwner: Change Owner
|
||||
textureType: Texture Type
|
||||
deletePlayer: Delete
|
||||
|
|
@ -343,7 +335,6 @@ general:
|
|||
player:
|
||||
owner: Owner
|
||||
player-name: Player Name
|
||||
preference: Preference
|
||||
previews: Texture Previews
|
||||
last-modified: Last Modified
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,5 @@ player:
|
|||
pid: PID
|
||||
owner: Owner
|
||||
player-name: Player Name
|
||||
preference: Preference
|
||||
previews: Texture Previews
|
||||
last-modified: Last Modified
|
||||
|
|
|
|||
|
|
@ -83,14 +83,6 @@ player:
|
|||
|
||||
login-notice: Now you can log in with player names you owned instead email address.
|
||||
|
||||
player-info: Information <small>(click player name to show preview)</small>
|
||||
|
||||
textures:
|
||||
steve: Steve Model:
|
||||
alex: Alex Model:
|
||||
cape: Cape:
|
||||
empty: Nothing
|
||||
|
||||
player-name-rule:
|
||||
official: Player name may only contains letters, numbers and underscores.
|
||||
cjk: Player name may contains letters, numbers, underscores and CJK Unified Ideographs.
|
||||
|
|
@ -116,11 +108,6 @@ player:
|
|||
clear:
|
||||
success: The textures of player :name was resetted successfully.
|
||||
|
||||
preference:
|
||||
title: Preference
|
||||
description: Default stands for the Steve model with 4-pixel width arms, and Slim for the Alex model with 3-pixel width arms.
|
||||
success: The preference of player :name was updated to :preference
|
||||
|
||||
profile:
|
||||
avatar:
|
||||
title: Change Avatar?
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
username: ':attribute format is invalid.'
|
||||
player_name: 'The :attribute contains invalid character.'
|
||||
no_special_chars: 'The :attribute must not contain special characters.'
|
||||
preference: 'The :attribute must be default or slim.'
|
||||
model: 'The :attribute must be steve, alex or cape.'
|
||||
|
||||
accepted: 'The :attribute must be accepted.'
|
||||
|
|
|
|||
|
|
@ -61,8 +61,6 @@ players:
|
|||
no-permission: 你无权操作此角色
|
||||
operations:
|
||||
title: 更多操作
|
||||
preference:
|
||||
success: 角色 :player 的优先模型已更改至 :preference
|
||||
textures:
|
||||
change: 更换材质
|
||||
non-existent: 材质 tid.:tid 不存在
|
||||
|
|
|
|||
|
|
@ -198,19 +198,12 @@ user:
|
|||
add-player: 添加新角色
|
||||
login-notice: 你现在可以使用你所拥有的角色名来登录皮肤站啦~
|
||||
player-info: 角色信息 <small>(点击角色名以查看预览)</small>
|
||||
textures:
|
||||
steve: Steve 模型的皮肤:
|
||||
alex: Alex 模型的皮肤:
|
||||
cape: 披风:
|
||||
empty: 未上传
|
||||
texture-empty: 未上传
|
||||
player-name-rule:
|
||||
official: 角色名只能包含拉丁字母、数字以及下划线。
|
||||
cjk: 角色名可使用拉丁字母、数字、下划线以及汉字(中日韩统一表意文字)。
|
||||
custom: 本站使用了自定义的角色名规则,详情请咨询站点管理员。
|
||||
player-name-length: 角色名最少要求 :min 个字符,最多不超过 :max 个字符。
|
||||
preference:
|
||||
title: 优先模型
|
||||
description: Default 即为默认的 Steve 模型(手臂 4 个像素宽),Slim 即为手臂宽 3 个像素的 Alex 模型。
|
||||
verification:
|
||||
title: 验证你的邮箱地址
|
||||
message: 你必须验证你的邮箱才能正常使用本站的皮肤托管等功能。没有收到验证邮件?
|
||||
|
|
@ -251,7 +244,6 @@ admin:
|
|||
changePlayerTexture: '更换角色 :player 的材质'
|
||||
changeTexture: 更换材质
|
||||
changePlayerName: 更改角色名
|
||||
changePreference: 切换模型
|
||||
changeOwner: 更换角色拥有者
|
||||
deletePlayer: 删除
|
||||
changePlayerOwner: 请输入此角色要让渡至的用户 UID:
|
||||
|
|
@ -337,7 +329,6 @@ general:
|
|||
player:
|
||||
owner: 拥有者
|
||||
player-name: 角色名
|
||||
preference: 优先模型
|
||||
previews: 预览材质
|
||||
last-modified: 修改时间
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,5 @@ player:
|
|||
pid: PID
|
||||
owner: 拥有者
|
||||
player-name: 角色名
|
||||
preference: 优先模型
|
||||
previews: 预览材质
|
||||
last-modified: 修改时间
|
||||
|
|
|
|||
|
|
@ -117,11 +117,6 @@ player:
|
|||
clear:
|
||||
success: 角色 :name 的材质已被成功重置
|
||||
|
||||
preference:
|
||||
title: 优先模型
|
||||
description: Default 即为默认的 Steve 模型(手臂 4 个像素宽),Slim 即为手臂宽 3 个像素的 Alex 模型。
|
||||
success: 角色 :name 的优先模型已更改至 :preference
|
||||
|
||||
profile:
|
||||
avatar:
|
||||
title: 更改头像?
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
username: ':attribute 格式错误。'
|
||||
player_name: ':attribute 不符合规则。'
|
||||
no_special_chars: ':attribute 不能包含特殊字符。'
|
||||
preference: ':attribute 的值必须为 default 或 slim。'
|
||||
model: ':attribute 的值必须为 steve、alex 或 cape。'
|
||||
|
||||
accepted: ':attribute 必须接受。'
|
||||
|
|
@ -89,7 +88,6 @@ attributes:
|
|||
new_nickname: 新昵称
|
||||
player_name: 角色名
|
||||
new_player_name: 新角色名
|
||||
preference: 优先模型
|
||||
model: 模型
|
||||
name: 名称
|
||||
new_name: 新名称
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ Route::group(['middleware' => 'player'], function()
|
|||
Route::get('/{api}/{player_name}.json', 'TextureController@jsonWithApi')->where('api', 'usm|csl');
|
||||
// Legacy links
|
||||
Route::get('/skin/{player_name}.png', 'TextureController@skin');
|
||||
Route::get('/skin/{model}/{pname}.png', 'TextureController@skinWithModel');
|
||||
Route::get('/cape/{player_name}.png', 'TextureController@cape');
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,6 @@ Route::group(['middleware' => ['web', 'auth'], 'prefix' => 'user'], function ()
|
|||
Route::get ('/list', 'PlayerController@listAll');
|
||||
Route::post('/add', 'PlayerController@add');
|
||||
Route::any ('/show', 'PlayerController@show');
|
||||
Route::post('/preference', 'PlayerController@setPreference');
|
||||
Route::post('/set', 'PlayerController@setTexture');
|
||||
Route::post('/texture/clear', 'PlayerController@clearTexture');
|
||||
Route::post('/rename', 'PlayerController@rename');
|
||||
|
|
|
|||
|
|
@ -200,9 +200,7 @@ class AdminControllerTest extends BrowserKitTestCase
|
|||
'pid',
|
||||
'uid',
|
||||
'player_name',
|
||||
'preference',
|
||||
'tid_steve',
|
||||
'tid_alex',
|
||||
'tid_skin',
|
||||
'tid_cape',
|
||||
'last_modified'
|
||||
]]
|
||||
|
|
@ -214,9 +212,7 @@ class AdminControllerTest extends BrowserKitTestCase
|
|||
'pid' => $player->pid,
|
||||
'uid' => $user->uid,
|
||||
'player_name' => $player->player_name,
|
||||
'preference' => $player->preference,
|
||||
'tid_steve' => $player->tid_steve,
|
||||
'tid_alex' => $player->tid_alex,
|
||||
'tid_skin' => $player->tid_skin,
|
||||
'tid_cape' => $player->tid_cape
|
||||
]]
|
||||
]);
|
||||
|
|
@ -504,45 +500,7 @@ class AdminControllerTest extends BrowserKitTestCase
|
|||
'msg' => trans('admin.users.operations.invalid')
|
||||
]);
|
||||
|
||||
// Change preference without `preference` field
|
||||
$this->postJson('/admin/players', [
|
||||
'pid' => $player->pid,
|
||||
'action' => 'preference'
|
||||
], [
|
||||
'Accept' => 'application/json',
|
||||
])->seeJson([
|
||||
'errno' => 1,
|
||||
'msg' => trans('validation.required', ['attribute' => 'preference'])
|
||||
]);
|
||||
|
||||
// Change preference but neither `default` nor `slim`
|
||||
$this->postJson('/admin/players', [
|
||||
'pid' => $player->pid,
|
||||
'action' => 'preference',
|
||||
'preference' => 'steve'
|
||||
], [
|
||||
'Accept' => 'application/json',
|
||||
])->seeJson([
|
||||
'errno' => 1,
|
||||
'msg' => trans('validation.preference', ['attribute' => 'preference'])
|
||||
]);
|
||||
|
||||
// Set preference successfully
|
||||
$this->postJson('/admin/players', [
|
||||
'pid' => $player->pid,
|
||||
'action' => 'preference',
|
||||
'preference' => 'slim'
|
||||
])->seeJson([
|
||||
'errno' => 0,
|
||||
'msg' => trans(
|
||||
'admin.players.preference.success',
|
||||
['player' => $player->player_name, 'preference' => 'slim']
|
||||
)
|
||||
]);
|
||||
$player = Player::find($player->pid);
|
||||
$this->assertEquals('slim', $player->preference);
|
||||
|
||||
// Change texture without `model` field
|
||||
// Change texture without `type` field
|
||||
$this->postJson('/admin/players', [
|
||||
'pid' => $player->pid,
|
||||
'action' => 'texture'
|
||||
|
|
@ -550,26 +508,14 @@ class AdminControllerTest extends BrowserKitTestCase
|
|||
'Accept' => 'application/json',
|
||||
])->seeJson([
|
||||
'errno' => 1,
|
||||
'msg' => trans('validation.required', ['attribute' => 'model'])
|
||||
]);
|
||||
|
||||
// Change texture with invalid model name
|
||||
$this->postJson('/admin/players', [
|
||||
'pid' => $player->pid,
|
||||
'action' => 'texture',
|
||||
'model' => 'slim'
|
||||
], [
|
||||
'Accept' => 'application/json',
|
||||
])->seeJson([
|
||||
'errno' => 1,
|
||||
'msg' => trans('validation.model', ['attribute' => 'model'])
|
||||
'msg' => trans('validation.required', ['attribute' => 'type'])
|
||||
]);
|
||||
|
||||
// Change texture without `tid` field
|
||||
$this->postJson('/admin/players', [
|
||||
'pid' => $player->pid,
|
||||
'action' => 'texture',
|
||||
'model' => 'steve'
|
||||
'type' => 'skin'
|
||||
], [
|
||||
'Accept' => 'application/json',
|
||||
])->seeJson([
|
||||
|
|
@ -581,7 +527,7 @@ class AdminControllerTest extends BrowserKitTestCase
|
|||
$this->postJson('/admin/players', [
|
||||
'pid' => $player->pid,
|
||||
'action' => 'texture',
|
||||
'model' => 'steve',
|
||||
'type' => 'skin',
|
||||
'tid' => 'string'
|
||||
], [
|
||||
'Accept' => 'application/json',
|
||||
|
|
@ -594,48 +540,34 @@ class AdminControllerTest extends BrowserKitTestCase
|
|||
$this->postJson('/admin/players', [
|
||||
'pid' => $player->pid,
|
||||
'action' => 'texture',
|
||||
'model' => 'steve',
|
||||
'type' => 'skin',
|
||||
'tid' => -1
|
||||
])->seeJson([
|
||||
'errno' => 1,
|
||||
'msg' => trans('admin.players.textures.non-existent', ['tid' => -1])
|
||||
]);
|
||||
|
||||
$steve = factory(Texture::class)->create();
|
||||
$alex = factory(Texture::class, 'alex')->create();
|
||||
$skin = factory(Texture::class)->create();
|
||||
$cape = factory(Texture::class, 'cape')->create();
|
||||
|
||||
// Steve
|
||||
// Skin
|
||||
$this->postJson('/admin/players', [
|
||||
'pid' => $player->pid,
|
||||
'action' => 'texture',
|
||||
'model' => 'steve',
|
||||
'tid' => $steve->tid
|
||||
'type' => 'skin',
|
||||
'tid' => $skin->tid
|
||||
])->seeJson([
|
||||
'errno' => 0,
|
||||
'msg' => trans('admin.players.textures.success', ['player' => $player->player_name])
|
||||
]);
|
||||
$player = Player::find($player->pid);
|
||||
$this->assertEquals($steve->tid, $player->tid_steve);
|
||||
|
||||
// Alex
|
||||
$this->postJson('/admin/players', [
|
||||
'pid' => $player->pid,
|
||||
'action' => 'texture',
|
||||
'model' => 'alex',
|
||||
'tid' => $alex->tid
|
||||
])->seeJson([
|
||||
'errno' => 0,
|
||||
'msg' => trans('admin.players.textures.success', ['player' => $player->player_name])
|
||||
]);
|
||||
$player = Player::find($player->pid);
|
||||
$this->assertEquals($alex->tid, $player->tid_alex);
|
||||
$this->assertEquals($skin->tid, $player->tid_skin);
|
||||
|
||||
// Cape
|
||||
$this->postJson('/admin/players', [
|
||||
'pid' => $player->pid,
|
||||
'action' => 'texture',
|
||||
'model' => 'cape',
|
||||
'type' => 'cape',
|
||||
'tid' => $cape->tid
|
||||
])->seeJson([
|
||||
'errno' => 0,
|
||||
|
|
@ -648,32 +580,20 @@ class AdminControllerTest extends BrowserKitTestCase
|
|||
$this->postJson('/admin/players', [
|
||||
'pid' => $player->pid,
|
||||
'action' => 'texture',
|
||||
'model' => 'steve',
|
||||
'type' => 'skin',
|
||||
'tid' => 0
|
||||
])->seeJson([
|
||||
'errno' => 0,
|
||||
'msg' => trans('admin.players.textures.success', ['player' => $player->player_name])
|
||||
]);
|
||||
$player = Player::find($player->pid);
|
||||
$this->assertEquals(0, $player->tid_steve);
|
||||
$this->assertNotEquals(0, $player->tid_alex);
|
||||
$this->assertEquals(0, $player->tid_skin);
|
||||
$this->assertNotEquals(0, $player->tid_cape);
|
||||
|
||||
$this->postJson('/admin/players', [
|
||||
'pid' => $player->pid,
|
||||
'action' => 'texture',
|
||||
'model' => 'alex',
|
||||
'tid' => 0
|
||||
])->seeJson([
|
||||
'errno' => 0,
|
||||
'msg' => trans('admin.players.textures.success', ['player' => $player->player_name])
|
||||
]);
|
||||
$player = Player::find($player->pid);
|
||||
$this->assertEquals(0, $player->tid_alex);
|
||||
$this->assertNotEquals(0, $player->tid_cape);
|
||||
$this->postJson('/admin/players', [
|
||||
'pid' => $player->pid,
|
||||
'action' => 'texture',
|
||||
'model' => 'cape',
|
||||
'type' => 'cape',
|
||||
'tid' => 0
|
||||
])->seeJson([
|
||||
'errno' => 0,
|
||||
|
|
|
|||
43
tests/CommandsTest/MigratePlayersTableTest.php
Normal file
43
tests/CommandsTest/MigratePlayersTableTest.php
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Faker;
|
||||
use Artisan;
|
||||
use App\Models\Player;
|
||||
use App\Console\Commands\MigratePlayersTable;
|
||||
use Illuminate\Foundation\Testing\WithoutMiddleware;
|
||||
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class MigratePlayersTableTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
public function testExecute()
|
||||
{
|
||||
$faker = Faker\Factory::create();
|
||||
|
||||
for ($i = 1; $i <= 10; $i++) {
|
||||
factory(Player::class)->create([
|
||||
'tid_skin' => -1,
|
||||
'preference' => $faker->randomElement(['default', 'slim']),
|
||||
'tid_steve' => $faker->randomDigit(),
|
||||
'tid_alex' => $faker->randomDigit(),
|
||||
]);
|
||||
}
|
||||
|
||||
Artisan::call('bs:migrate-v4:players-table');
|
||||
|
||||
Player::all()
|
||||
->each(function (Player $player) {
|
||||
if ($player->preference == 'default') {
|
||||
$this->assertEquals($player->tid_steve, $player->tid_skin);
|
||||
} else {
|
||||
$this->assertEquals($player->tid_alex, $player->tid_skin);
|
||||
}
|
||||
});
|
||||
|
||||
$this->assertEquals(0, Artisan::call('bs:migrate-v4:players-table'));
|
||||
}
|
||||
}
|
||||
|
|
@ -14,19 +14,11 @@ class PlayerTest extends TestCase
|
|||
|
||||
public function testGetTexture()
|
||||
{
|
||||
$steve = factory(Texture::class)->create();
|
||||
$alex = factory(Texture::class, 'alex')->create();
|
||||
$player = factory(Player::class)->create([
|
||||
'tid_steve' => $steve->tid,
|
||||
'tid_alex' => $alex->tid
|
||||
]);
|
||||
$skin = factory(Texture::class)->create();
|
||||
$player = factory(Player::class)->create(['tid_skin' => $skin->tid]);
|
||||
|
||||
$player = Player::find($player->pid);
|
||||
$this->assertEquals($steve->hash, $player->getTexture('skin'));
|
||||
|
||||
$player->setPreference('slim');
|
||||
$player = Player::find($player->pid);
|
||||
$this->assertEquals($alex->hash, $player->getTexture('skin'));
|
||||
$this->assertEquals($skin->hash, $player->getTexture('skin'));
|
||||
|
||||
$this->assertFalse($player->getTexture('invalid_type'));
|
||||
}
|
||||
|
|
@ -46,4 +38,23 @@ class PlayerTest extends TestCase
|
|||
$this->expectsEvents(\App\Events\PlayerProfileUpdated::class);
|
||||
$player->updateLastModified();
|
||||
}
|
||||
|
||||
public function testGetTidSkinAttribute()
|
||||
{
|
||||
$player = factory(Player::class)->create([
|
||||
'tid_skin' => -1,
|
||||
'preference' => 'default',
|
||||
'tid_steve' => 5,
|
||||
]);
|
||||
$this->assertEquals(5, $player->tid_skin);
|
||||
$this->assertEquals(5, Player::find($player->pid)->tid_skin);
|
||||
|
||||
$player = factory(Player::class)->create([
|
||||
'tid_skin' => -1,
|
||||
'preference' => 'slim',
|
||||
'tid_alex' => 6,
|
||||
]);
|
||||
$this->assertEquals(6, $player->tid_skin);
|
||||
$this->assertEquals(6, Player::find($player->pid)->tid_skin);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,20 +30,13 @@ class PlayerControllerTest extends TestCase
|
|||
public function testListAll()
|
||||
{
|
||||
$user = factory(User::class)->create();
|
||||
$default = factory(Player::class)->create(['uid' => $user->uid]);
|
||||
$slim = factory(Player::class, 'slim')->create(['uid' => $user->uid]);
|
||||
$player = factory(Player::class)->create(['uid' => $user->uid]);
|
||||
$this->actingAs($user)
|
||||
->get('/user/player/list')
|
||||
->assertJson([
|
||||
[
|
||||
'pid' => $default->pid,
|
||||
'player_name' => $default->player_name,
|
||||
'preference' => $default->preference,
|
||||
],
|
||||
[
|
||||
'pid' => $slim->pid,
|
||||
'player_name' => $slim->player_name,
|
||||
'preference' => $slim->preference,
|
||||
'pid' => $player->pid,
|
||||
'player_name' => $player->player_name,
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
|
@ -109,7 +102,6 @@ class PlayerControllerTest extends TestCase
|
|||
$this->assertNotNull($player);
|
||||
$this->assertEquals($user->uid, $player->uid);
|
||||
$this->assertEquals('角色名', $player->player_name);
|
||||
$this->assertEquals('default', $player->preference);
|
||||
$this->assertEquals(
|
||||
$score - option('score_per_player'),
|
||||
User::find($user->uid)->score
|
||||
|
|
@ -233,42 +225,28 @@ class PlayerControllerTest extends TestCase
|
|||
{
|
||||
$player = factory(Player::class)->create();
|
||||
$user = $player->user;
|
||||
$steve = factory(Texture::class)->create();
|
||||
$alex = factory(Texture::class, 'alex')->create();
|
||||
$skin = factory(Texture::class)->create();
|
||||
$cape = factory(Texture::class, 'cape')->create();
|
||||
|
||||
// Set a not-existed texture
|
||||
$this->actAs($user)
|
||||
->postJson('/user/player/set', [
|
||||
'pid' => $player->pid,
|
||||
'tid' => ['steve' => -1]
|
||||
'tid' => ['skin' => -1]
|
||||
])->assertJson([
|
||||
'errno' => 6,
|
||||
'msg' => trans('skinlib.un-existent')
|
||||
]);
|
||||
|
||||
// Set for "alex" type
|
||||
// Model preference should be automatically set to "slim"
|
||||
// Set for "skin" type
|
||||
$this->postJson('/user/player/set', [
|
||||
'pid' => $player->pid,
|
||||
'tid' => ['alex' => $alex->tid]
|
||||
'tid' => ['skin' => $skin->tid]
|
||||
])->assertJson([
|
||||
'errno' => 0,
|
||||
'msg' => trans('user.player.set.success', ['name' => $player->player_name])
|
||||
]);
|
||||
$this->expectsEvents(Events\PlayerProfileUpdated::class);
|
||||
$this->assertEquals(Player::find($player->pid)->preference, 'slim');
|
||||
$this->assertEquals($alex->tid, Player::find($player->pid)->tid_alex);
|
||||
|
||||
// Set for "steve" type
|
||||
$this->postJson('/user/player/set', [
|
||||
'pid' => $player->pid,
|
||||
'tid' => ['steve' => $steve->tid]
|
||||
])->assertJson([
|
||||
'errno' => 0,
|
||||
'msg' => trans('user.player.set.success', ['name' => $player->player_name])
|
||||
]);
|
||||
$this->assertEquals($steve->tid, Player::find($player->pid)->tid_steve);
|
||||
$this->assertEquals($skin->tid, Player::find($player->pid)->tid_skin);
|
||||
|
||||
// Set for "cape" type
|
||||
$this->postJson('/user/player/set', [
|
||||
|
|
@ -283,28 +261,11 @@ class PlayerControllerTest extends TestCase
|
|||
// Invalid texture type is acceptable
|
||||
$this->postJson('/user/player/set', [
|
||||
'pid' => $player->pid,
|
||||
'tid' => ['nope' => $steve->tid] // TID must be valid
|
||||
'tid' => ['nope' => $skin->tid] // TID must be valid
|
||||
])->assertJson([
|
||||
'errno' => 0,
|
||||
'msg' => trans('user.player.set.success', ['name' => $player->player_name])
|
||||
]);
|
||||
|
||||
// Should be OK if texture type does not match
|
||||
$this->postJson('/user/player/set', [
|
||||
'pid' => $player->pid,
|
||||
'tid' => [
|
||||
'steve' => $alex->tid,
|
||||
'alex' => $cape->tid,
|
||||
'cape' => $steve->tid
|
||||
]
|
||||
])->assertJson([
|
||||
'errno' => 0,
|
||||
'msg' => trans('user.player.set.success', ['name' => $player->player_name])
|
||||
]);
|
||||
$player = Player::find($player->pid);
|
||||
$this->assertEquals($steve->tid, $player->tid_steve);
|
||||
$this->assertEquals($alex->tid, $player->tid_alex);
|
||||
$this->assertEquals($cape->tid, $player->tid_cape);
|
||||
}
|
||||
|
||||
public function testClearTexture()
|
||||
|
|
@ -313,9 +274,8 @@ class PlayerControllerTest extends TestCase
|
|||
$user = $player->user;
|
||||
|
||||
$player->setTexture([
|
||||
'tid_steve' => 1,
|
||||
'tid_alex' => 2,
|
||||
'tid_cape' => 3
|
||||
'tid_skin' => 1,
|
||||
'tid_cape' => 2
|
||||
]);
|
||||
$player = Player::find($player->pid);
|
||||
|
||||
|
|
@ -323,58 +283,14 @@ class PlayerControllerTest extends TestCase
|
|||
$this->actAs($user)
|
||||
->postJson('/user/player/texture/clear', [
|
||||
'pid' => $player->pid,
|
||||
'steve' => 1, // "1" stands for "true"
|
||||
'alex' => 1,
|
||||
'skin' => 1, // "1" stands for "true"
|
||||
'cape' => 1,
|
||||
'nope' => 1, // Invalid texture type is acceptable
|
||||
])->assertJson([
|
||||
'errno' => 0,
|
||||
'msg' => trans('user.player.clear.success', ['name' => $player->player_name])
|
||||
]);
|
||||
$this->assertEquals(0, Player::find($player->pid)->tid_steve);
|
||||
$this->assertEquals(0, Player::find($player->pid)->tid_alex);
|
||||
$this->assertEquals(0, Player::find($player->pid)->tid_skin);
|
||||
$this->assertEquals(0, Player::find($player->pid)->tid_cape);
|
||||
}
|
||||
|
||||
public function testSetPreference()
|
||||
{
|
||||
// Without `preference` field
|
||||
$player = factory(Player::class)->create();
|
||||
$this->actAs($player->user)
|
||||
->postJson('/user/player/preference', [
|
||||
'pid' => $player->pid
|
||||
], [
|
||||
'X-Requested-With' => 'XMLHttpRequest'
|
||||
])->assertJson([
|
||||
'errno' => 1,
|
||||
'msg' => trans('validation.required', ['attribute' => 'preference'])
|
||||
]);
|
||||
|
||||
// value of `preference` is invalid
|
||||
$this->postJson('/user/player/preference', [
|
||||
'pid' => $player->pid,
|
||||
'preference' => 'steve'
|
||||
], [
|
||||
'X-Requested-With' => 'XMLHttpRequest'
|
||||
])->assertJson([
|
||||
'errno' => 1,
|
||||
'msg' => trans('validation.preference', ['attribute' => 'preference'])
|
||||
]);
|
||||
|
||||
// Success
|
||||
$this->expectsEvents(Events\PlayerProfileUpdated::class);
|
||||
$this->postJson('/user/player/preference', [
|
||||
'pid' => $player->pid,
|
||||
'preference' => 'slim'
|
||||
], [
|
||||
'X-Requested-With' => 'XMLHttpRequest'
|
||||
])->assertJson([
|
||||
'errno' => 0,
|
||||
'msg' => trans(
|
||||
'user.player.preference.success',
|
||||
['name' => $player->player_name, 'preference' => 'slim']
|
||||
)
|
||||
]);
|
||||
$this->assertEquals('slim', Player::find($player->pid)->preference);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -793,14 +793,14 @@ class SkinlibControllerTest extends TestCase
|
|||
$texture = factory(Texture::class)->create(['uploader' => $uploader->uid]);
|
||||
$uploader->score += $texture->size * option('private_score_per_storage');
|
||||
$uploader->save();
|
||||
$player = factory(Player::class)->create(['tid_steve' => $texture->tid]);
|
||||
$player = factory(Player::class)->create(['tid_skin' => $texture->tid]);
|
||||
$this->postJson('/skinlib/privacy', ['tid' => $texture->tid])
|
||||
->assertJson([
|
||||
'errno' => 0,
|
||||
'msg' => trans('skinlib.privacy.success', ['privacy' => trans('general.private')]),
|
||||
'public' => false
|
||||
]);
|
||||
$this->assertEquals(0, Player::find($player->pid)->tid_steve);
|
||||
$this->assertEquals(0, Player::find($player->pid)->tid_skin);
|
||||
}
|
||||
|
||||
public function testRename()
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ class TextureControllerTest extends TestCase
|
|||
->assertStatus(404);
|
||||
|
||||
// Player is banned
|
||||
$player = factory(Player::class)->create(['tid_steve' => $steve->tid]);
|
||||
$player = factory(Player::class)->create(['tid_skin' => $steve->tid]);
|
||||
$player->user->setPermission(User::BANNED);
|
||||
$this->get("/{$player->player_name}.json")
|
||||
->assertSee(trans('general.player-banned'))
|
||||
|
|
@ -39,8 +39,7 @@ class TextureControllerTest extends TestCase
|
|||
->assertJson([
|
||||
'username' => $player->player_name,
|
||||
'skins' => [
|
||||
'default' => $steve->hash,
|
||||
'slim' => null
|
||||
'default' => $steve->hash
|
||||
],
|
||||
'cape' => null
|
||||
])->assertHeader('Last-Modified');
|
||||
|
|
@ -49,15 +48,15 @@ class TextureControllerTest extends TestCase
|
|||
public function testJsonWithApi()
|
||||
{
|
||||
$steve = factory(Texture::class)->create();
|
||||
$player = factory(Player::class)->create(['tid_steve' => $steve->tid]);
|
||||
$alex = factory(Texture::class, 'alex')->create();
|
||||
$player = factory(Player::class)->create(['tid_skin' => $steve->tid]);
|
||||
|
||||
// CSL API
|
||||
$this->getJson("/csl/{$player->player_name}.json")
|
||||
->assertJson([
|
||||
'username' => $player->player_name,
|
||||
'skins' => [
|
||||
'default' => $steve->hash,
|
||||
'slim' => null
|
||||
'default' => $steve->hash
|
||||
],
|
||||
'cape' => null
|
||||
])->assertHeader('Last-Modified');
|
||||
|
|
@ -66,13 +65,38 @@ class TextureControllerTest extends TestCase
|
|||
$this->getJson("/usm/{$player->player_name}.json")
|
||||
->assertJson([
|
||||
'player_name' => $player->player_name,
|
||||
'model_preference' => ['default', 'slim'],
|
||||
'model_preference' => ['default'],
|
||||
'skins' => [
|
||||
'default' => $steve->hash,
|
||||
'slim' => null
|
||||
'default' => $steve->hash
|
||||
],
|
||||
'cape' => null
|
||||
])->assertHeader('Last-Modified');
|
||||
|
||||
$player->tid_skin = $alex->tid;
|
||||
$player->save();
|
||||
|
||||
// CSL API
|
||||
$this->getJson("/csl/{$player->player_name}.json")
|
||||
->assertJson([
|
||||
'username' => $player->player_name,
|
||||
'skins' => [
|
||||
'default' => $alex->hash,
|
||||
'slim' => $alex->hash
|
||||
],
|
||||
'cape' => null
|
||||
]);
|
||||
|
||||
// USM API
|
||||
$this->getJson("/usm/{$player->player_name}.json")
|
||||
->assertJson([
|
||||
'player_name' => $player->player_name,
|
||||
'model_preference' => ['slim'],
|
||||
'skins' => [
|
||||
'default' => $alex->hash,
|
||||
'slim' => $alex->hash
|
||||
],
|
||||
'cape' => null
|
||||
]);
|
||||
}
|
||||
|
||||
public function testTexture()
|
||||
|
|
@ -115,46 +139,26 @@ class TextureControllerTest extends TestCase
|
|||
|
||||
public function testSkin()
|
||||
{
|
||||
$steve = factory(Texture::class)->create();
|
||||
$player = factory(Player::class)->create([
|
||||
'preference' => 'slim',
|
||||
'tid_steve' => $steve->tid,
|
||||
'tid_alex' => 0
|
||||
]);
|
||||
$skin = factory(Texture::class)->create();
|
||||
$player = factory(Player::class)->create();
|
||||
|
||||
$this->get("/skin/{$player->player_name}.png")
|
||||
->assertSee(trans('general.texture-not-uploaded', ['type' => 'alex']));
|
||||
->assertSee(trans('general.texture-not-uploaded', ['type' => 'skin']));
|
||||
|
||||
$player->setPreference('default');
|
||||
$player->tid_skin = $skin->tid;
|
||||
$player->save();
|
||||
$this->get("/skin/{$player->player_name}.png")
|
||||
->assertSee(trans('general.texture-deleted'));
|
||||
|
||||
Storage::disk('textures')->put($steve->hash, '');
|
||||
Storage::disk('textures')->put($skin->hash, '');
|
||||
$this->get("/skin/{$player->player_name}.png")
|
||||
->assertHeader('Content-Type', 'image/png')
|
||||
->assertHeader('Last-Modified')
|
||||
->assertHeader('Accept-Ranges', 'bytes')
|
||||
->assertHeader('Content-Length', Storage::disk('textures')->size($steve->hash))
|
||||
->assertHeader('Content-Length', Storage::disk('textures')->size($skin->hash))
|
||||
->assertSuccessful();
|
||||
}
|
||||
|
||||
public function testSkinWithModel()
|
||||
{
|
||||
$steve = factory(Texture::class)->create();
|
||||
$player = factory(Player::class)->create([
|
||||
'preference' => 'slim',
|
||||
'tid_steve' => $steve->tid,
|
||||
'tid_alex' => 0
|
||||
]);
|
||||
|
||||
$this->get("/skin/alex/{$player->player_name}.png")
|
||||
->assertSee(trans('general.texture-not-uploaded', ['type' => 'alex']));
|
||||
|
||||
$player->setPreference('default');
|
||||
$this->get("/skin/steve/{$player->player_name}.png")
|
||||
->assertSee(trans('general.texture-deleted'));
|
||||
}
|
||||
|
||||
public function testCape()
|
||||
{
|
||||
$cape = factory(Texture::class, 'cape')->create();
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user