mirror of
https://github.com/lkddi/nexusphp.git
synced 2026-04-19 00:01:00 +08:00
finish announce api
This commit is contained in:
@@ -65,9 +65,9 @@ class Test extends Command
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
$peer = Peer::query()->first();
|
||||
echo $peer->prev_action->timestamp;
|
||||
$redis = Redis::connection()->client();
|
||||
$r = $redis->get('5da94a358e67cb5181166ae2611c2fd9');
|
||||
dd($r);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,96 +2,24 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Resources\AgentDenyResource;
|
||||
use App\Models\AgentDeny;
|
||||
use App\Repositories\AgentDenyRepository;
|
||||
use App\Repositories\TrackerRepository;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class TrackerController extends Controller
|
||||
{
|
||||
private $repository;
|
||||
private TrackerRepository $repository;
|
||||
|
||||
public function __construct(AgentDenyRepository $repository)
|
||||
public function __construct(TrackerRepository $repository)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
private function getRules(): array
|
||||
{
|
||||
return [
|
||||
'family_id' => 'required|numeric',
|
||||
'name' => 'required|string',
|
||||
'peer_id' => 'required|string',
|
||||
'agent' => 'required|string',
|
||||
'comment' => 'required|string',
|
||||
|
||||
];
|
||||
}
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$result = $this->repository->getList($request->all());
|
||||
$resource = AgentDenyResource::collection($result);
|
||||
return $this->success($resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
public function announce(Request $request): \Illuminate\Http\Response
|
||||
{
|
||||
$request->validate($this->getRules());
|
||||
$result = $this->repository->store($request->all());
|
||||
$resource = new AgentDenyResource($result);
|
||||
return $this->success($resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return array
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
$result = AgentDeny::query()->findOrFail($id);
|
||||
$resource = new AgentDenyResource($result);
|
||||
return $this->success($resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return array
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$request->validate($this->getRules());
|
||||
$result = $this->repository->update($request->all(), $id);
|
||||
$resource = new AgentDenyResource($result);
|
||||
return $this->success($resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return array
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
$result = $this->repository->delete($id);
|
||||
return $this->success($result);
|
||||
return $this->repository->announce($request);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +89,7 @@ class Peer extends NexusModel
|
||||
$tmp_ip = '['.$tmp_ip.']';
|
||||
}
|
||||
$cacheKey = 'peers:connectable:'.$tmp_ip.'-'.$this->port.'-'.$this->agent;
|
||||
$log = "cacheKey: $cacheKey";
|
||||
if (!Cache::has($cacheKey)) {
|
||||
$con = @fsockopen($tmp_ip, $this->port, $error_code, $error_message, 1);
|
||||
if (is_resource($con)) {
|
||||
@@ -98,6 +99,10 @@ class Peer extends NexusModel
|
||||
$this->connectable = self::CONNECTABLE_NO;
|
||||
}
|
||||
Cache::put($cacheKey, $this->connectable, 600);
|
||||
$log .= ", do check, connectable: " . $this->connectable;
|
||||
} else {
|
||||
$log .= ", don't do check";
|
||||
}
|
||||
do_log($log);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,11 @@ class Snatch extends NexusModel
|
||||
{
|
||||
protected $table = 'snatched';
|
||||
|
||||
protected $fillable = [
|
||||
'torrentid', 'userid', 'ip', 'port', 'uploaded', 'downloaded', 'to_go', 'seedtime', 'leechtime',
|
||||
'last_action', 'startdat', 'completedat', 'finished'
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'last_action' => 'datetime',
|
||||
'startdat' => 'datetime',
|
||||
|
||||
@@ -116,7 +116,7 @@ class User extends Authenticatable
|
||||
*/
|
||||
protected $fillable = [
|
||||
'username', 'email', 'passhash', 'secret', 'stylesheet', 'editsecret', 'added', 'modcomment', 'enabled', 'status',
|
||||
'leechwarn', 'leechwarnuntil', 'page', 'class'
|
||||
'leechwarn', 'leechwarnuntil', 'page', 'class', 'uploaded', 'downloaded', 'clientselect', 'showclienterror',
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -46,6 +46,10 @@ class RouteServiceProvider extends ServiceProvider
|
||||
Route::middleware('web')
|
||||
->namespace($this->namespace)
|
||||
->group(base_path('routes/web.php'));
|
||||
|
||||
Route::prefix('api')
|
||||
->namespace($this->namespace)
|
||||
->group(base_path('routes/tracker.php'));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -56,9 +56,9 @@ class AgentAllowRepository extends BaseRepository
|
||||
}
|
||||
$matchCount = count($matches) - 1;
|
||||
//due to old data may be matchNum > matchCount
|
||||
if ($matchNum > $matchCount && !IN_NEXUS) {
|
||||
throw new ClientNotAllowedException("pattern: $pattern match start: $start got matches count: $matchCount, but require $matchNum.");
|
||||
}
|
||||
// if ($matchNum > $matchCount && !IN_NEXUS) {
|
||||
// throw new ClientNotAllowedException("pattern: $pattern match start: $start got matches count: $matchCount, but require $matchNum.");
|
||||
// }
|
||||
return array_slice($matches, 1, $matchNum);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,9 +12,9 @@ use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Exceptions\TrackerException;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Redis;
|
||||
use Nexus\Database\NexusDB;
|
||||
use Rhilip\Bencode\Bencode;
|
||||
|
||||
class TrackerRepository extends BaseRepository
|
||||
@@ -26,8 +26,6 @@ class TrackerRepository extends BaseRepository
|
||||
const MUST_BE_CHEATER_SPEED = 1024 * 1024 * 1024; //1024 MB/s
|
||||
const MAY_BE_CHEATER_SPEED = 1024 * 1024 * 100; //100 MB/s
|
||||
|
||||
private array $userUpdates = [];
|
||||
|
||||
// Port Blacklist
|
||||
protected const BLACK_PORTS = [
|
||||
22, // SSH Port
|
||||
@@ -42,13 +40,17 @@ class TrackerRepository extends BaseRepository
|
||||
6699, // Port used by p2p software, such as WinMX, Napster.
|
||||
];
|
||||
|
||||
private array $userUpdates = [];
|
||||
|
||||
public function announce(Request $request): \Illuminate\Http\Response
|
||||
{
|
||||
do_log(nexus_json_encode($_SERVER));
|
||||
try {
|
||||
$withPeers = false;
|
||||
$queries = $this->checkAnnounceFields($request);
|
||||
$clientAllow = $this->checkClient($request);
|
||||
do_log("[QUERIES] " . json_encode(Arr::only($queries, ['ip', 'user_agent', 'uploaded', 'downloaded', 'left', 'event'])), 'debug');
|
||||
$user = $this->checkUser($request);
|
||||
$clientAllow = $this->checkClient($request);
|
||||
$torrent = $this->checkTorrent($queries, $user);
|
||||
if ($this->isReAnnounce($queries) === false) {
|
||||
$withPeers = true;
|
||||
@@ -65,14 +67,17 @@ class TrackerRepository extends BaseRepository
|
||||
} else {
|
||||
$this->checkCheater($torrent, $queries, $user, $peerSelf);
|
||||
}
|
||||
/**
|
||||
* Note: Must get before update peer!
|
||||
*/
|
||||
$dataTraffic = $this->getDataTraffic($torrent, $queries, $user, $peerSelf);
|
||||
|
||||
$this->updatePeer($peerSelf, $queries);
|
||||
$this->updateSnatch($peerSelf, $queries);
|
||||
$this->updateSnatch($peerSelf, $queries, $dataTraffic);
|
||||
$this->updateTorrent($torrent, $queries);
|
||||
|
||||
$dataTraffic = $this->getRealUploadedDownloaded($torrent, $queries, $user, $peerSelf);
|
||||
$this->userUpdates['uploaded'] = DB::raw('uploaded + ' . $dataTraffic['uploaded']);
|
||||
$this->userUpdates['downloaded'] = DB::raw('downloaded + ' . $dataTraffic['downloaded']);
|
||||
$this->userUpdates['uploaded'] = DB::raw('uploaded + ' . $dataTraffic['uploaded_increment_for_user']);
|
||||
$this->userUpdates['downloaded'] = DB::raw('downloaded + ' . $dataTraffic['downloaded_increment_for_user']);
|
||||
$this->userUpdates['clientselect'] = $clientAllow->id;
|
||||
$this->userUpdates['showclienterror'] = 'no';
|
||||
}
|
||||
@@ -80,13 +85,17 @@ class TrackerRepository extends BaseRepository
|
||||
} catch (ClientNotAllowedException $exception) {
|
||||
do_log("[ClientNotAllowedException] " . $exception->getMessage());
|
||||
$this->userUpdates['showclienterror'] = 'yes';
|
||||
$repDict = $this->generateFailedAnnounceResponse($exception);
|
||||
$repDict = $this->generateFailedAnnounceResponse($exception->getMessage());
|
||||
} catch (TrackerException $exception) {
|
||||
do_log("[TrackerException] " . $exception->getMessage());
|
||||
$repDict = $this->generateFailedAnnounceResponse($exception);
|
||||
$repDict = $this->generateFailedAnnounceResponse($exception->getMessage());
|
||||
} catch (\Exception $exception) {
|
||||
//other system exception
|
||||
do_log("[" . get_class($exception) . "] " . $exception->getMessage() . "\n" . $exception->getTraceAsString(), 'error');
|
||||
$repDict = $this->generateFailedAnnounceResponse("system error, report to sysop please, hint: " . REQUEST_ID);
|
||||
} finally {
|
||||
if (isset($user)) {
|
||||
if (isset($user) && count($this->userUpdates)) {
|
||||
$user->update($this->userUpdates);
|
||||
do_log(last_query(), 'debug');
|
||||
}
|
||||
return $this->sendFinalAnnounceResponse($repDict);
|
||||
}
|
||||
@@ -132,7 +141,8 @@ class TrackerRepository extends BaseRepository
|
||||
}
|
||||
|
||||
$agentAllowRep = new AgentAllowRepository();
|
||||
$agentAllowRep->checkClient($request->peer_id, $userAgent);
|
||||
|
||||
return $agentAllowRep->checkClient($request->peer_id, $userAgent, config('app.debug'));
|
||||
|
||||
}
|
||||
|
||||
@@ -235,11 +245,11 @@ class TrackerRepository extends BaseRepository
|
||||
// Part.5 Get Users Agent
|
||||
$queries['user_agent'] = $request->headers->get('user-agent');
|
||||
|
||||
// Part.6 bin2hex info_hash
|
||||
$queries['info_hash'] = \bin2hex($queries['info_hash']);
|
||||
// Part.6 info_hash, binary
|
||||
$queries['info_hash'] = $queries['info_hash'];
|
||||
|
||||
// Part.7 bin2hex peer_id
|
||||
$queries['peer_id'] = \bin2hex($queries['peer_id']);
|
||||
// Part.7
|
||||
$queries['peer_id'] = $queries['peer_id'];
|
||||
|
||||
return $queries;
|
||||
}
|
||||
@@ -247,9 +257,9 @@ class TrackerRepository extends BaseRepository
|
||||
protected function checkUser(Request $request)
|
||||
{
|
||||
if ($authkey = $request->query->get('authkey')) {
|
||||
list($torrentId, $uid) = $this->checkAuthkey($authkey);
|
||||
$checkResult = $this->checkAuthkey($authkey);
|
||||
$field = 'id';
|
||||
$value = $uid;
|
||||
$value = $checkResult['uid'];
|
||||
} elseif ($passkey = $request->query->get('passkey')) {
|
||||
$this->checkPasskey($passkey);
|
||||
$field = 'passkey';
|
||||
@@ -370,10 +380,14 @@ class TrackerRepository extends BaseRepository
|
||||
$peer = Peer::query()
|
||||
->where('torrent', $torrent->id)
|
||||
->where('peer_id', $queries['peer_id'])
|
||||
->where('userid', $user->id)
|
||||
->first();
|
||||
|
||||
if ($peer && $peer->isValidDate('prev_action') && Carbon::now()->diffInSeconds($peer->prev_action) < self::MIN_ANNOUNCE_WAIT_SECOND) {
|
||||
if (
|
||||
$peer
|
||||
&& $queries['event'] == ''
|
||||
&& $peer->isValidDate('prev_action')
|
||||
&& Carbon::now()->diffInSeconds($peer->prev_action) < self::MIN_ANNOUNCE_WAIT_SECOND
|
||||
) {
|
||||
throw new TrackerException('There is a minimum announce time of ' . self::MIN_ANNOUNCE_WAIT_SECOND . ' seconds');
|
||||
}
|
||||
return $peer;
|
||||
@@ -484,6 +498,7 @@ class TrackerRepository extends BaseRepository
|
||||
'peers' => [],
|
||||
'peers6' => [],
|
||||
];
|
||||
do_log("[REP_DICT_BASE] " . json_encode($repDict));
|
||||
if (!$withPeers) {
|
||||
return $repDict;
|
||||
}
|
||||
@@ -509,7 +524,7 @@ class TrackerRepository extends BaseRepository
|
||||
} else {
|
||||
$peers = $baseQuery->get()->toArray();
|
||||
}
|
||||
|
||||
do_log("[REP_DICT_PEER_QUERY] " . last_query());
|
||||
$repDict['peers'] = $this->givePeers($peers, $queries['compact'], $queries['no_peer_id']);
|
||||
$repDict['peers6'] = $this->givePeers($peers, $queries['compact'], $queries['no_peer_id'], FILTER_FLAG_IPV6);
|
||||
}
|
||||
@@ -544,28 +559,42 @@ class TrackerRepository extends BaseRepository
|
||||
return $real_annnounce_interval;
|
||||
}
|
||||
|
||||
private function getRealUploadedDownloaded(Torrent $torrent, $queries, User $user, Peer $peer): array
|
||||
private function getDataTraffic(Torrent $torrent, $queries, User $user, Peer $peer): array
|
||||
{
|
||||
$log = sprintf(
|
||||
"torrent: %s, user: %s, peer: %s, queriesUploaded: %s, queriesDownloaded: %s",
|
||||
$torrent->id, $user->id, $peer->id, $queries['uploaded'], $queries['downloaded']
|
||||
);
|
||||
if ($peer->exists) {
|
||||
$realUploaded = max($queries['uploaded'] - $peer->uploaded, 0);
|
||||
$realDownloaded = max($queries['downloaded'] - $peer->downloaded, 0);
|
||||
$log .= ", [PEER_EXISTS], realUploaded: $realUploaded, realDownloaded: $realDownloaded";
|
||||
} else {
|
||||
$realUploaded = $queries['uploaded'];
|
||||
$realDownloaded = $queries['downloaded'];
|
||||
$log .= ", [PEER_NOT_EXISTS],, realUploaded: $realUploaded, realDownloaded: $realDownloaded";
|
||||
}
|
||||
$spStateReal = $torrent->spStateReal;
|
||||
$uploaderRatio = Setting::get('torrent.uploaderdouble');
|
||||
$log .= ", spStateReal: $spStateReal, uploaderRatio: $uploaderRatio";
|
||||
if ($torrent->owner == $user->id) {
|
||||
//uploader, use the bigger one
|
||||
$upRatio = max($uploaderRatio, Torrent::$promotionTypes[$spStateReal]['up_multiplier']);
|
||||
$log .= ", [IS_UPLOADER], upRatio: $upRatio";
|
||||
} else {
|
||||
$upRatio = Torrent::$promotionTypes[$spStateReal]['up_multiplier'];
|
||||
$log .= ", [IS_NOT_UPLOADER], upRatio: $upRatio";
|
||||
}
|
||||
$downRatio = Torrent::$promotionTypes[$spStateReal]['down_multiplier'];
|
||||
return [
|
||||
'uploaded' => $realUploaded * $upRatio,
|
||||
'downloaded' => $realDownloaded * $downRatio
|
||||
$log .= ", downRatio: $downRatio";
|
||||
$result = [
|
||||
'uploaded_increment' => $realUploaded,
|
||||
'uploaded_increment_for_user' => $realUploaded * $upRatio,
|
||||
'downloaded_increment' => $realDownloaded,
|
||||
'downloaded_increment_for_user' => $realDownloaded * $downRatio,
|
||||
];
|
||||
do_log("$log, result: " . json_encode($result));
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function givePeers($peers, $compact, $noPeerId, int $filterFlag = FILTER_FLAG_IPV4): string|array
|
||||
@@ -593,10 +622,10 @@ class TrackerRepository extends BaseRepository
|
||||
return $peers;
|
||||
}
|
||||
|
||||
protected function generateFailedAnnounceResponse(\Exception $exception): array
|
||||
protected function generateFailedAnnounceResponse($reason): array
|
||||
{
|
||||
return [
|
||||
'failure reason' => $exception->getMessage(),
|
||||
'failure reason' => $reason,
|
||||
'min interval' => self::MIN_ANNOUNCE_WAIT_SECOND,
|
||||
//'retry in' => self::MIN_ANNOUNCE_WAIT_SECOND
|
||||
];
|
||||
@@ -631,12 +660,15 @@ class TrackerRepository extends BaseRepository
|
||||
}
|
||||
|
||||
$torrent->save();
|
||||
do_log(last_query(), 'debug');
|
||||
}
|
||||
|
||||
private function updatePeer(Peer $peer, $queries)
|
||||
{
|
||||
if ($queries['event'] == 'stopped') {
|
||||
return $peer->delete();
|
||||
$peer->delete();
|
||||
do_log(last_query(), 'debug');
|
||||
return;
|
||||
}
|
||||
|
||||
$nowStr = Carbon::now()->toDateTimeString();
|
||||
@@ -648,23 +680,34 @@ class TrackerRepository extends BaseRepository
|
||||
|
||||
$peer->to_go = $queries['left'];
|
||||
$peer->seeder = $queries['left'] == 0 ? 'yes' : 'no';
|
||||
$peer->prev_action = DB::raw('last_action');
|
||||
$peer->last_action = $nowStr;
|
||||
$peer->uploaded = $queries['uploaded'];
|
||||
$peer->downloaded = $queries['downloaded'];
|
||||
|
||||
if ($peer->exists) {
|
||||
$peer->prev_action = $peer->last_action;
|
||||
}
|
||||
|
||||
if ($queries['event'] == 'started') {
|
||||
$peer->started = $nowStr;
|
||||
$peer->uploadoffset = $queries['uploaded'];
|
||||
$peer->downloadoffset = $queries['downloaded'];
|
||||
} elseif ($queries['event'] == 'completed') {
|
||||
$peer->finishat = time();
|
||||
$peer->finishedat = time();
|
||||
}
|
||||
|
||||
$peer->save();
|
||||
do_log(last_query(), 'debug');
|
||||
}
|
||||
|
||||
private function updateSnatch(Peer $peer, $queries)
|
||||
/**
|
||||
* Update snatch, uploaded & downloaded, use the increment value to do increment
|
||||
*
|
||||
* @param Peer $peer
|
||||
* @param $queries
|
||||
* @param $dataTraffic
|
||||
*/
|
||||
private function updateSnatch(Peer $peer, $queries, $dataTraffic)
|
||||
{
|
||||
$nowStr = Carbon::now()->toDateTimeString();
|
||||
|
||||
@@ -679,13 +722,13 @@ class TrackerRepository extends BaseRepository
|
||||
//initial
|
||||
$snatch->torrentid = $peer->torrent;
|
||||
$snatch->userid = $peer->userid;
|
||||
$snatch->uploaded = $queries['uploaded'];
|
||||
$snatch->downloaded = $queries['downloaded'];
|
||||
$snatch->startat = $nowStr;
|
||||
$snatch->uploaded = $dataTraffic['uploaded_increment'];
|
||||
$snatch->downloaded = $dataTraffic['downloaded_increment'];
|
||||
$snatch->startdat = $nowStr;
|
||||
} else {
|
||||
//increase
|
||||
$snatch->uploaded = DB::raw("uploaded + " . $queries['uploaded']);
|
||||
$snatch->downloaded = DB::raw("downloaded + " . $queries['downloaded']);
|
||||
//increase, use the increment value
|
||||
$snatch->uploaded = DB::raw("uploaded + " . $dataTraffic['uploaded_increment']);
|
||||
$snatch->downloaded = DB::raw("downloaded + " . $dataTraffic['downloaded_increment']);
|
||||
$timeIncrease = Carbon::now()->diffInSeconds($peer->last_action);
|
||||
if ($queries['left'] == 0) {
|
||||
//seeder
|
||||
@@ -699,7 +742,7 @@ class TrackerRepository extends BaseRepository
|
||||
//always update
|
||||
$snatch->ip = $queries['ip'];
|
||||
$snatch->port = $queries['port'];
|
||||
$snatch->to_go = $queries['to_go'];
|
||||
$snatch->to_go = $queries['left'];
|
||||
$snatch->last_action = $nowStr;
|
||||
if ($queries['event'] == 'completed') {
|
||||
$snatch->completedat = $nowStr;
|
||||
@@ -707,6 +750,7 @@ class TrackerRepository extends BaseRepository
|
||||
}
|
||||
|
||||
$snatch->save();
|
||||
do_log(last_query(), 'debug');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddIndexToCheatersTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('cheaters', function (Blueprint $table) {
|
||||
$table->index('torrentid');
|
||||
$table->index('userid');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('cheaters', function (Blueprint $table) {
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -352,6 +352,7 @@ return array (
|
||||
'watermarkquality' => '85',
|
||||
'altthumbwidth' => '180',
|
||||
'altthumbheight' => '135',
|
||||
'download_support_passkey' => 'yes',
|
||||
),
|
||||
'advertisement' =>
|
||||
array (
|
||||
|
||||
@@ -79,3 +79,5 @@ Route::group(['middleware' => ['auth:sanctum', 'locale']], function () {
|
||||
|
||||
Route::post('login', [\App\Http\Controllers\AuthenticateController::class, 'login']);
|
||||
|
||||
Route::get('announce', [\App\Http\Controllers\TrackerController::class, 'announce']);
|
||||
|
||||
|
||||
4
routes/tracker.php
Normal file
4
routes/tracker.php
Normal file
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::get('announce', [\App\Http\Controllers\TrackerController::class, 'announce']);
|
||||
@@ -14,5 +14,5 @@ use Illuminate\Support\Facades\Route;
|
||||
*/
|
||||
|
||||
Route::get('/', function () {
|
||||
return view('welcome');
|
||||
return redirect('https://nexusphp.org');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user