初始化

This commit is contained in:
2026-03-02 13:44:38 +08:00
commit 05b785083c
677 changed files with 58662 additions and 0 deletions

View File

@@ -0,0 +1,511 @@
<?php
namespace app\service\game;
use addons\webman\model\Game;
use addons\webman\model\GamePlatform;
use addons\webman\model\Player;
use addons\webman\model\PlayerGamePlatform;
use addons\webman\model\PlayerWalletTransfer;
use app\exception\GameException;
use Exception;
use support\Response;
class JDBServiceInterface extends GameServiceFactory implements GameServiceInterface
{
public $method = 'POST';
public $successCode = '0000';
public $loginId;
public $gameType = [
'10' => 'Slot',
'12' => 'Casino',
'13' => 'Arcade',
'16' => 'Fishing'
];
public $failCode = [
'0000' => '成功',
'9999' => '失敗',
'9001' => '未授權訪問',
'9002' => '域名為空或域名長度小於 2',
'9003' => '域名驗證失敗。',
'9004' => '加密數據為空或加密數據的長度等於 0。',
'9005' => '斷言SAML未通過時間戳驗證。',
'9006' => '從加密數據中提取 SAML 參數失敗。',
'9007' => '未知操作。',
'9008' => '與之前的值相同。',
'9009' => '超時。',
'9010' => '讀取超時。',
'9011' => '重複交易。',
'9012' => '請稍後再試。',
'9013' => '系統正在維護。',
'9014' => '檢測到多帳戶登錄。',
'9015' => '數據不存在。',
'9016' => '無效令牌。',
'9019' => '請求速率限制超過。',
'9020' => '每次登錄只能獲得一次遊戲票。',
'9021' => '違反一次性會話策略。',
'9022' => '遊戲正在維護。',
'9023' => '不支持的貨幣。',
'9024' => '贏取倍數必須大於或等於 10 倍。',
'9025' => '不支持重放遊戲。',
'9026' => '获胜金额应大于0。',
'9027' => '不支持演示。',
'8000' => '輸入參數錯誤,請檢查您的參數是否正確。',
'8001' => '參數不能為空。',
'8002' => '參數必須是正整數。',
'8003' => '參數不能為負數。',
'8005' => '日期秒格式錯誤',
'8006' => '時間不符合。',
'8007' => '參數只能使用數字。',
'8008' => '找不到參數。',
'8009' => '時間間隔超過允許範圍。',
'8010' => '參數長度太長。',
'8013' => '日期分鐘格式參數錯誤。',
'8014' => '參數不得超過指定的小數位。',
'7001' => '找不到指定的父 ID。',
'7002' => '父級已暫停。',
'7003' => '父級已鎖定。',
'7004' => '父級已關閉。',
'7405' => '您已登出!',
'7501' => '找不到用戶 ID。',
'7502' => '用戶已暫停。',
'7503' => '用戶已鎖定。',
'7504' => '用戶已關閉。',
'7505' => '用戶未在玩遊戲。',
'7506' => '演示帳戶已滿。',
'7601' => '無效的用戶 ID。請僅使用 a-z、0-9 之間的字符。',
'7602' => '帳戶已存在。請選擇其他用戶 ID。',
'7603' => '無效的用戶名。',
'7604' => '密碼必須至少 6 個字符,包含 1 個字母和 1 個數字。',
'7605' => '無效的操作代碼。請僅使用數字 2、3、4、5。',
'6001' => '您的現金餘額不足以取款。',
'6002' => '用戶餘額為零。',
'6003' => '取款金額為負。',
'6004' => '重複轉帳。',
'6005' => '重複的序列號。',
'6009' => '存款金額超過上限。',
'6010' => '餘額超過上限。',
'6011' => '分配的信用額超過上限。',
'6012' => '序列號正在進行中。',
'6901' => '用戶正在玩遊戲,不允許轉移餘額。'
];
private $apiDomain;
private $domain;
private $iv;
private $key;
private $dc;
private $parent;
private $lang = [
'zh-CN' => 'cn',
'zh-TW' => 'cn',
'jp' => 'jpn',
'en' => 'en',
'th' => 'th',
'vi' => 'vi',
'kr_ko' => 'ko',
'id' => 'id',
];
public $localGameType = [
'0' => '1',//斯洛
'32' => '1',//斯洛
'50' => '1',//斯洛
'55' => '1',//斯洛
'57' => '1',//斯洛
'58' => '1',//斯洛
'66' => '1',//斯洛
'80' => '1',//斯洛
'90' => '1',//斯洛
'130' => '1',//斯洛
'7' => '4',//捕鱼
'31' => '4',//捕鱼
'70' => '4',//捕鱼
'59' => '4',//捕鱼
'67' => '4',//捕鱼
'91' => '4',//捕鱼
'8' => '8',//宾果
'12' => '8',//宾果
'60' => '8',//宾果
'9' => '8',//宾果
'22' => '8',//宾果
'30' => '8',//宾果
'56' => '8',//宾果
'75' => '8',//宾果
'81' => '8',//宾果
'92' => '8',//宾果
'131' => '8',//宾果
'120' => '8',//宾果
'18' => '2',//赌场
'93' => '2',//赌场
'132' => '2',//赌场
'41' => '5',//真人视讯
'101' => '5',//真人视讯
];
/**
* @param Player|null $player
* @param $type
* @throws Exception
*/
public function __construct($type, Player $player = null)
{
$config = config('game_platform.' . $type);
$this->iv = $config['iv'];
$this->apiDomain = $config['api_domain'].'/apiRequest.do';
$this->domain = $config['domain'];
$this->key = $config['key'];
$this->dc = $config['dc'];
$this->parent = $config['admin_user'];
$this->platform = GamePlatform::query()->where('name', $type)->first();
if (!empty($player)) {
$this->player = $player;
$this->getLoginId();
}
}
/**
* 生成请求数据
* @param $source
* @return string
*/
public function padString($source): string
{
$paddingChar = ' ';
$size = 16;
$x = strlen($source) % $size;
$padLength = $size - $x;
$source .= str_repeat($paddingChar, $padLength);
return $source;
}
/**
* 生成请求数据
* @param $params
* @return array
*/
public function buildParams($params): array
{
$data = $this->padString(json_encode($params));
$encryptData = openssl_encrypt($data, 'AES-128-CBC', $this->key, OPENSSL_NO_PADDING, $this->iv);
$reqBase64 = base64_encode($encryptData);
return [
'dc' => $this->dc,
'x' => str_replace(array('+','/','=') , array('-','_','') , $reqBase64)
];
}
/**
* @throws Exception
*/
protected function getLoginId()
{
/** @var PlayerGamePlatform $playerGamePlatform */
$playerGamePlatform = PlayerGamePlatform::query()
->where('platform_id', $this->platform->id)
->where('player_id',$this->player->id)
->first();
if (!empty($playerGamePlatform)) {
return $this->loginId = $playerGamePlatform->player_code;
}
return $this->createPlayer([
'uuid' => $this->player->uuid,
'name' => $this->player->name,
]);
}
/**
* 创建玩家
* @param array $data
* @return array|mixed|Response
* @throws GameException|\think\Exception
*/
public function createPlayer(array $data = [])
{
$params = [
'action' => 12,
'ts' => round(microtime(true) * 1000),
'lang' => 'cn',
'parent' => $this->parent,
'uid' => $this->player->uuid,
'name' => $this->player->name ?: $this->player->uuid
];
$request = $this->buildParams($params);
$res = doFormCurl($this->apiDomain, $request);
if ($res['status'] != $this->successCode) {
throw new GameException($this->failCode[$res['status']], 0);
}
$playerGamePlatform = new PlayerGamePlatform();
$playerGamePlatform->player_id = $this->player->id;
$playerGamePlatform->platform_id = $this->platform->id;
$playerGamePlatform->player_name = $data['name'];
$playerGamePlatform->player_code = $data['uuid'];
$playerGamePlatform->save();
$this->loginId = $playerGamePlatform->player_code;
return $res;
}
public function getPlayer()
{
// TODO: Implement getPlayer() method.
}
/**
* 获取游戏摘要MD5 (id+method+sn+APlSecretKey)
* @return array|mixed|Response
* @throws GameException|\think\Exception
*/
public function getSimpleGameList()
{
$params = [
'action' => 49,
'ts' => round(microtime(true) * 1000),
'parent' => $this->parent,
'lang' => 'en',
];
$request = $this->buildParams($params);
$res = doFormCurl($this->apiDomain, $request);
if ($res['status'] != $this->successCode) {
throw new GameException($this->failCode[$res['status']], 0);
}
$insertData = [];
if (!empty($res['data'])) {
foreach ($res['data'] as $data) {
foreach($data['list'] as $item){
$insertData[] = [
'platform_id' => $this->platform->id,
'game_code' => $item['mType'],
'platform_game_type' => $data['gType'],
'game_type' => $this->localGameType[$data['gType']],
'name' => $item['name'],
'game_image' => $item['image'],
];
}
}
}
if (!empty($insertData)) {
Game::query()->upsert($insertData, ['platform_id', 'game_code']);
}
return $insertData;
}
/**
* 获取游戏摘要MD5 (id+method+sn+APlSecretKey)
* @param array $data
* @return string
* @throws GameException|\think\Exception
*/
public function login(array $data = []): string
{
$params = [
'action' => 11,
'ts' => round(microtime(true) * 1000),
'lang' => $this->lang[$data['lang']] ?? 'en',
'uid' => $this->loginId,
'gType' => $data['platformGameType'],
'mType' => $data['gameCode'],
'windowMode' => 2,
'isAPP' => true,
];
// if($data['platformGameType'] || $data['gameCode']){
// $params['gType'] = $data['platformGameType'];
// $params['mType'] = $data['gameCode'];
// $params['windowMode'] = 2;
// $params['isAPP'] = true;
// }
$request = $this->buildParams($params);
$res = doFormCurl($this->apiDomain, $request);
if ($res['status'] != $this->successCode) {
throw new GameException($this->failCode[$res['status']], 0);
}
return $res['path'] ?? '';
}
/**
* 玩家钱包转入游戏平台
* @return array|mixed|null
* @throws GameException|\think\Exception
*/
public function balanceTransferOut()
{
return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_OUT, $this->player->wallet->money);
}
/**
* 转入游戏平台玩家钱包
* @return array|mixed|null
* @throws GameException|\think\Exception
*/
public function balanceTransferIn()
{
//提现之前把用户踢下线
if($this->checkPlay()){
$this->userLogout();
sleep(1);
}
$balance = $this->getBalance();
if($balance == 0){
// 记录玩家钱包转出转入记录
$this->createWalletTransfer(PlayerWalletTransfer::TYPE_IN, 0, 0);
return true;
}
return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_IN, $balance ? -$balance : 0);
}
/**
* 轉帳進出額度
* @param $type
* @param float $amount
* @param float $reward
* @return array|mixed|null
* @throws GameException|\think\Exception
*/
protected function setBalanceTransfer($type, float $amount = 0, float $reward = 0)
{
$params = [
'action' => 19,
'ts' => round(microtime(true) * 1000),
'parent' => $this->parent,
'uid' => $this->loginId,
'serialNo' => createOrderNo(),
'amount' => $amount ?? 0,
];
$request = $this->buildParams($params);
$res = doFormCurl($this->apiDomain, $request);
if ($res['status'] != $this->successCode) {
throw new GameException($this->failCode[$res['status']], 0);
}
// 记录玩家钱包转出转入记录
$this->createWalletTransfer($type, $amount, $reward);
return $res;
}
/**
* 獲取玩家餘額信息
* @return array|mixed|Response
* @throws GameException|\think\Exception
*/
public function getBalance()
{
$params = [
'action' => 15,
'ts' => round(microtime(true) * 1000),
'parent' => $this->parent,
'uid' => $this->loginId,
];
$request = $this->buildParams($params);
$res = doFormCurl($this->apiDomain, $request);
if ($res['status'] != $this->successCode) {
throw new GameException('JDB System Error,Please contact the administrator', 0);
}
return $res['data'][0]['balance'] ?? 0;
}
/**
* 查询玩家状态
* @throws GameException|\think\Exception
*/
public function checkPlay(): bool
{
$params = [
'action' => 52,
'ts' => round(microtime(true) * 1000),
'parent' => $this->parent,
'uid' => $this->loginId,
];
$request = $this->buildParams($params);
$res = doFormCurl($this->apiDomain, $request);
//游戏中
if($res['status'] == $this->successCode){
return true;
}
//不在游戏中
if($res['status'] == 7505){
return false;
}
throw new GameException($this->failCode[$res['status']], 0);
}
/**
* 玩家踢下线
* @throws GameException|\think\Exception
*/
public function userLogout(): bool
{
$params = [
'action' => 17,
'ts' => round(microtime(true) * 1000),
'parent' => $this->parent,
'uid' => $this->loginId,
];
$request = $this->buildParams($params);
$res = doFormCurl($this->apiDomain, $request);
if ($res['status'] != $this->successCode) {
throw new GameException($this->failCode[$res['status']], 0);
}
return true;
}
/**
* 取得區間內遊戲紀錄
* @return array
* @throws Exception
*/
public function handleOrderHistories(): array
{
$list = [];
try {
$data = $this->getGameHistories();
if (!empty($data)) {
foreach ($data as $item) {
if ($item['gType'] == 9 && !empty($item['hasGamble'])) {
$item['bet'] = $item['gambleBet'];
}
$list[] = [
'uuid' => $item['playerId'],
'platform_id' => $this->platform->id,
'game_code' => $item['mtype'],
'bet' => abs($item['bet']),
'win' => max($item['win'], 0),
'order_no' => $item['historyId'],
'game_type' => $item['gType'],
'original_data' => json_encode($item,JSON_UNESCAPED_UNICODE),
'platform_action_at' => date('Y-m-d H:i:s', strtotime($item['lastModifyTime'])),
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
];
}
}
} catch (Exception $e) {
return [];
}
return $list;
}
/**
* 取得區間內遊戲紀錄
* @return array
* @throws GameException|\think\Exception
*/
public function getGameHistories(): array
{
$params = [
'action' => 29,
'ts' => round(microtime(true) * 1000),
'parent' => $this->parent,
'starttime' => date('d-m-Y H:i:00', strtotime('-5 minutes')),
'endtime' => date('d-m-Y H:i:00', strtotime('-4 minutes')),
];
$request = $this->buildParams($params);
$res = doFormCurl($this->apiDomain, $request);
if ($res['status'] != $this->successCode) {
throw new GameException($this->failCode[$res['status']], 0);
}
return $res['data'] ?? [];
}
}