<?php
/**
* 名称:4399存档接口
* 出处:https://www.yowal.cn/
* 时间:2023年05月26日
*/
class StoreUtils {
private $raw_data;
private $current_byte;
function __construct($rd = "") {
$this->current_byte = 0;
$this->raw_data = base64_decode(str_replace(' ','+', $rd));//你post/get传递可能会把+号替换成空格,所以这里直接把空格替换成+号即可
}
public function uncompress() {
$this->current_byte = 0;
$this->raw_data = zlib_decode($this->raw_data);
}
private function read() {
return ord($this->raw_data[$this->current_byte++]);
}
private function readUInt29() {
$b = $this->read() & 255;
if ($b < 128) {
return $b;
}
$value = ($b & 127) << 7;
$b = $this->read() & 255;
if ($b < 128) {
return ($value | $b);
}
$value = ($value | ($b & 127)) << 7;
$b = $this->read() & 255;
if ($b < 128) {
return ($value | $b);
}
$value = ($value | ($b & 127)) << 8;
$b = $this->read() & 255;
return ($value | $b);
}
private function readUnsignedShort() {
$c1 = $this->read();
$c2 = $this->read();
return (($c1 << 8) + ($c2 << 0));
}
private function readUTF($length) {
$utflen = $length ? $length : $this->readUnsignedShort();
if ($utflen == 0) {
return "";
}
$val = substr($this->raw_data, $this->current_byte, $utflen);
$this->current_byte += $utflen;
return $val;
}
private function readString() {
$ref = $this->readUInt29();
if (($ref & 1) == 0) {
return "";
}
$len = ($ref >> 1);
$str = $this->readUTF($len);
return $str;
}
public function readObject() {
$type = $this->read();
if ($type == 6) {
return $this->readString();
}
return "";
}
// 下面是写数据
public function compress() {
$this->raw_data = zlib_encode($this->raw_data, ZLIB_ENCODING_DEFLATE, 9);
}
private function write($val) {
$this->raw_data .= pack("c", $val);
}
private function writeUInt29($v) {
if ($v < 128) {
$this->write($v);
} else if ($v < 16384) {
$this->write((($v >> 7) & 127) | 128);
$this->write($v & 127);
} else if ($v < 2097152) {
$this->write((($v >> 14) & 127) | 128);
$this->write((($v >> 7) & 127) | 128);
$this->write($v & 127);
} else if ($v < 0x40000000) {
$this->write((($v >> 22) & 127) | 128);
$this->write((($v >> 15) & 127) | 128);
$this->write((($v >> 8) & 127) | 128);
$this->write($v & 255);
}
}
private function writeUTF($v) {
$len = strlen($v);
$this->writeUInt29(($len << 1) | 1);
$this->raw_data .= $v;
}
public function writeObject($val) {
$this->write(0x06);
$this->writeUTF($val);
}
public function getBase64() {
return base64_encode($this->raw_data);
}
}
class GameUtils {
private $gameID;
private $sessionId;
private $userinfo;
// 默认是造梦西游3的游戏ID 可以通过抓包抓到
function __construct($rd = "100015389") {
$this->gameID = $rd;
}
private function formatData($arry) {
$ret = "";
foreach ($arry as $key => $value) {
$ret .= $key."=".urlencode($value)."&";
}
return substr($ret, 0, strlen($ret) - 1);
}
private function curl_get($url, $post = 0, $cookie = 0, $header = false, $content_type = "application/x-www-form-urlencoded", $split = false) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
$httpheader[] = "Content-Type:".$content_type;
curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
if ($post) {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
}
if ($header) {
curl_setopt($ch, CURLOPT_HEADER, TRUE);
}
if ($cookie) {
curl_setopt($ch, CURLOPT_COOKIE, $cookie);
}
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$ret = curl_exec($ch);
if ($split) {
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$header = substr($ret, 0, $headerSize);
$body = substr($ret, $headerSize);
$ret = array();
$ret['header'] = $header;
$ret['body'] = $body;
}
curl_close($ch);
return $ret;
}
private function getSubStr($str, $leftStr, $rightStr){
$left = strpos($str, $leftStr);
$right = strpos($str, $rightStr, $left);
if ($left < 0 || $right < $left) return "";
return substr($str, $left + strlen($leftStr), $right - $left - strlen($leftStr));
}
public function checkCaptcha($username) {
$response = $this->curl_get("https://ptlogin.4399.com/ptlogin/verify.do?username=".urlencode($username)."&appId=www_home&t=".time()."&inputWidth=iptw2");
if ($response != "0") {
$this->$sessionId = $this->getSubStr($response,"UniLoginChangPIC('","');");
return true;
}
$this->$sessionId = "";
return false;
}
//返回的是Base64编码
public function getCaptcha($isOcr = false) {
$response = $this->curl_get("http://ptlogin.4399.com/ptlogin/captcha.do?captchaId=".$this->$sessionId);
$ImageBase64 = base64_encode($response);
if (!$response) return $ImageBase64;
$post_data = json_encode(array('ImageBase64' => $ImageBase64),JSON_UNESCAPED_SLASHES);
$response = $this->curl_get("https://ocr.yowal.cn/identify_GeneralCAPTCHA", $post_data, 0, 0,"application/json");
$json = json_decode($response, true);
return $json["result"];
}
public function login($username, $password, $captcha = "") {
$post_data = array();
$post_data["username"] = $username;
$post_data["password"] = $password;
$post_data["sec"] = 0;
$post_data["appId"] = "www_home";
$post_data["inputCaptcha"] = $captcha;
$post_data["sessionId"] = $this->$sessionId;
$response = $this->curl_get("https://ptlogin.4399.com/ptlogin/login.do?v=1", $this->formatData($post_data), 0, true);
preg_match_all('/Set-Cookie: (.*);/iU', $response, $matchs);
foreach ($matchs[1] as $val) {
$cookie.=$val.'; ';
}
$this->$userinfo = array();
if (strpos($cookie, 'Pauth') !== false) {
$this->$userinfo['result'] = true;
$this->$userinfo['cookie'] = $cookie;
$this->$userinfo['user'] = $username;
$this->$userinfo['uid'] = $this->getSubStr($cookie,"Pauth=","|");
$this->$userinfo['nick'] = urldecode($this->getSubStr($cookie,"Pnick=",";"));
return $this->$userinfo;
}
$this->$userinfo['result'] = false;
$this->$userinfo['error'] = $this->getSubStr($response,"errorCallback('","')");
return $this->$userinfo;
}
private function saveKey() {
$hash = md5(md5($this->gameID."LPislKLodlLKKOSNlSDOAADLKADJAOADALAklsd".$this->gameID));
return substr($hash, 4, 16);
}
private function getVerify($str) {
return md5(md5(md5("SDALPlsldlnSLWPElsdslSE".$str."PKslsO")));
}
//返回解析后的存档列表
public function get_list($isarry = true) {
$post_data = array();
$post_data["uid"] = $this->$userinfo['uid'];
$post_data["gameid"] = $this->gameID;
$post_data["token"] = "";
$post_data["gamekey"] = $this->saveKey();
$post_data["verify"] = $this->getVerify($post_data["gamekey"].$this->$userinfo['uid'].$this->gameID.$post_data["token"]);
$response = $this->curl_get("https://save.api.4399.com/?ac=get_list", $this->formatData($post_data), $this->$userinfo['cookie']);
return json_decode($response, $isarry);
}
//返回解析后的存档数据
public function get_store($index = 0, $isarry = true) {
$post_data = array();
$post_data["index"] = $index;
$post_data["session"] = -1;
$post_data["uid"] = $this->$userinfo['uid'];
$post_data["gameid"] = $this->gameID;
$post_data["token"] = "";
$post_data["gamekey"] = $this->saveKey();
$post_data["verify"] = $this->getVerify($index.$post_data["gamekey"].$this->$userinfo['uid'].$this->gameID.$post_data["token"]);
$response = $this->curl_get("https://save.api.4399.com/?ac=get", $this->formatData($post_data), $this->$userinfo['cookie']);
return json_decode($response, $isarry);
}
//返回 1 为保存成功
public function save_store($index = 0, $title, $store) {
$post_data = array();
$post_data["session"] = -1;
$post_data["index"] = $index;
$post_data["uid"] = $this->$userinfo['uid'];
$post_data["gameid"] = $this->gameID;
$post_data["title"] = $title;
$post_data["data"] = $store;
$post_data["token"] = "";
$post_data["gamekey"] = $this->saveKey();
$post_data["verify"] = $this->getVerify($index.$post_data["gamekey"].$store.$title.$this->$userinfo['uid'].$this->gameID.$post_data["token"]);
$response = $this->curl_get("https://save.api.4399.com/?ac=save", $this->formatData($post_data), $this->$userinfo['cookie']);
return $response;
}
}
$username = "填写账号";
$password = "填写密码";
$game = new GameUtils();
if ($game->checkCaptcha($username)) {
$captcha = $game->getCaptcha(true);//这个识别不准,建议自己写前端,让用户自己填
echo "识别出验证码:".$captcha. "\n";
}
$userinfo = $game->login($username,$password, $captcha);
if ($userinfo['result'] == false) {
die("登录失败:".$userinfo['error']);
}
echo "昵称:".$userinfo['nick']." | UID:".$userinfo['uid']. "\n";
$json_list = $game->get_list();
foreach ($json_list as $obj) {
echo "index:".$obj['index'] ." | ";
echo "title:".$obj['title'] ." | ";
echo "datetime:".$obj['datetime'] ." | ";
echo "status:".$obj['status'] ."\n";
}
//下面读取存档
$json_store = $game->get_store(2);
$reader = new StoreUtils($json_store['data']);
$reader->uncompress();
$decocedData = $reader->readObject();
echo $decocedData;
//修改代码后就可以这样取需要保存的数据
//$writer = new StoreUtils();
//$writer->writeObject($decocedData);
//$writer->compress();
//echo $game->save_store(3,"极品猴子",$writer->getBase64());
//echo $writer->getBase64() == $json_store['data'] ? "数据相同" : "数据不同";//这里编码数据后看看是否和原始的相同
?>
这是一份用php写的 4399 swf小游戏存档接口的源码,功能齐全,可登录,可获取存档数据,保存存档,本源码仅供学习和交流,请勿用于非法用途
4 条评论
要是有一份e的就好了
也有的,开源在精易论坛
大佬牛逼
可以