本篇教程将是最短的教程了!因为前面我们的工作已经做得非常完美了!
首先,我们得知道,在前面几个章节,我们已经做了充足的准备了,因此我们只需要做一个按钮用于刷新我们的账号部分,即可了!
众所周知,我们所有的启动验证令牌,也就是我们的AccessToken,其实是有时效性的,其中AccessToken有24小时,而RefreshToken有1个月,因此,我们需要让玩家在AccessToken过期的时候,及时让他们刷新启动令牌,否则启动游戏后会直接显示无法进入Realms和多人游戏啦!
首先,先给大家提个醒,在PCL2、HMCL、BakaXL等众多第三方启动器中,一般是会直接在启动游戏时先对网站进行判断是否过期,如果不是,则无需重置,如果是,则为玩家重置一次账号部分!但是我的示例教程启动器为了更加方便演示,我就直接用按钮写了……而且注意一点,我的启动器在启动时,不会检测AccessToken是否过期,将会直接拼接AccessToken。所以,判断AccessToken是否过期这种操作,就留给大家当作作业了,大家自己去看看wiki上是怎么写有关于判断过期的,我这里就不多说了哈!
我把微软的Microsoft登录,微软的OAuth登录以及Authlib-Injector登录的刷新都给大家写上去吧了,大家尽情观看吧!
//重置账号的按钮
procedure TForm3.Button7Click(Sender: TObject);
begin
if tp = -1 then
begin //判断是否登录过账号,如果暂未登录,则返回!
messagebox(Handle, '你还没有选择登陆任何一个账号,请选择一个然后再重置吧!', '暂未选择,请重试', MB_ICONERROR);
exit;
end;
var pdmic: Boolean;
var pdthr: Boolean;
var pdoah: Boolean;
try //判断是否找得到账号,同时判断是否为微软登录。
var acc := ((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).GetValue('type').Value;
pdmic := acc <> 'microsoft'; //判断acc是否不等于microsoft,以下均是如此
pdthr := acc <> 'authlib-injector';
pdoah := acc <> 'oauth';
if pdmic and pdthr and pdoah then raise Exception.Create('Read Account Error'); //判断是否为微软或者外置。
except //此处,如果选择了离线登录的话,则跳出报错!
messagebox(Handle, '离线登录不能重置!', '离线登录不能重置', MB_OK+MB_ICONERROR);
exit;
end; //如果确认重置了的话,
if messagebox(Handle, '是否真的需要重置【微软/外置】登录?可能会需要等待久一点,不过你可以等的是么?', '是否需要', MB_YESNO+MB_ICONINFORMATION) = 6 then begin //选择重置
if not pdmic then begin //此时选中的是重置普通微软账号
var cpro: TProc := procedure begin
try //给其重置,定义一个accm变量,用于调用refresh_token。
var accm := Account.InitializeAccount(((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).GetValue('refresh_token').Value, 'refresh');
var at := accm.GetAccessToken; //获取AccessToken,如果获取成功且不为noneaccount的话,则往下
if at = 'noneaccount' then begin
exit;
end;
var rt := accm.GetRefreshToken; //获取RefreshToken
var uu := accm.GetUUID; //获取UUID
var un := accm.GetUserName;
var sk := accm.GetHeadSkin;
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).RemovePair('name');
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).RemovePair('uuid');
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).RemovePair('access_token');
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).RemovePair('refresh_token');//删除键
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).AddPair('name', un);
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).AddPair('uuid', uu);
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).AddPair('access_token', at);
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).AddPair('refresh_token', rt);//增加键
messagebox(Handle, '重置成功!', '重置成功', MB_ICONINFORMATION); //重置完成时会有个信息框提示
except //如果获取不了,则抛出报错。
messagebox(Handle, '你的refresh_token似乎也过期了呢!请尝试删除账号,重新登录一次吧!当然啦,或许只是网络不好的原因吧。。', '依旧过期', MB_OK+MB_ICONERROR); //如果无法重置,则抛出一个报错。例如在InitializeAccount的时候出现错误。
exit;
end;
end;
TTask.Run(cpro);//使用一个另一线程执行以上操作。
end;
if not pdoah then begin
TTask.Run(procedure begin //这里用了一个更加简便的方式,直接用TTask.Run里面包住一个procedure,其实这就相当于C#中的lambda表达式啦!
try //这里,我们需要获取两个东西,第一个就是我们的client_id,第二个就是我们的refresh_token了,CLIENT_ID我们其实也是需要的噢!
var reftoken := ((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).GetValue('refresh_token').Value;
var accm := Account.InitializeOAuth(CLIENT_ID, reftoken, 'refresh'); //依旧的……
var at := accm.GetAccessToken; //获取AccessToken
if at = 'noneaccount' then begin
exit;
end;
var rt := accm.GetRefreshToken; //获取RefreshToken
var uu := accm.GetUUID; //获取UUID
var un := accm.GetUserName;
var sk := accm.GetHeadSkin;
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).RemovePair('name');
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).RemovePair('uuid');
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).RemovePair('access_token');
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).RemovePair('refresh_token');//删除键
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).AddPair('name', un);
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).AddPair('uuid', uu);
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).AddPair('access_token', at);
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).AddPair('refresh_token', rt);//增加键
messagebox(Handle, '重置成功!', '重置成功', MB_ICONINFORMATION);
except
messagebox(Handle, '你的refresh_token似乎也过期了呢!请尝试删除账号,重新登录一次吧!当然啦,或许只是网络不好的原因吧。。', '依旧过期', MB_OK+MB_ICONERROR);
exit;
end;
end);
end;
if not pdthr then begin //这里,我们使用的是第三方登录噢!
var cpro: TProc := procedure begin //又用回老方法了……
try //这里我们就不定义变量了,采取换行的措施来搞!首先,我们获取了server,然后是access_token,然后是client_token,然后是uuid,然后是name。
var taccm := Account.InitializeAccount(
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).GetValue('server').Value,
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).GetValue('access_token').Value,
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).GetValue('client_token').Value,
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).GetValue('uuid').Value,
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).GetValue('name').Value, 'refresh'); //最后添加一个refresh,然后右括号结尾!
var ttat := taccm.GetThirdAccessToken; //是的,此时我们获取的是GetThirdAccesssToken,这个在上一章节我们没有说到,不过大家应该会自己写了吧……
if ttat = 'noneaccount' then begin
exit;
end;
var ttct := taccm.GetThirdClientToken; //剩下的都是老样子了……
var ttun := taccm.GetThirdUserName;
var ttuu := taccm.GetThirdUUID;
var ttsk := taccm.GetThirdHeadSkin;
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).RemovePair('name');
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).RemovePair('uuid');
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).RemovePair('access_token');
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).RemovePair('client_token');//删除键
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).AddPair('name', ttun);
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).AddPair('uuid', ttuu);
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).AddPair('access_token', ttat);
((AccountJson.GetValue('account') as TJsonArray)[tp] as TJsonObject).AddPair('client_token', ttct);//增加键
messagebox(Handle, '重置完成!', '重置完成', MB_OK+MB_ICONINFORMATION);
except
messagebox(Handle, '你的refresh_token似乎过期很久了呢!请尝试删除账号,重新登录一次吧!当然啦,或许只是网络不好的原因吧。。', '依旧过期', MB_OK+MB_ICONERROR);
exit;
end;
end; //这里还是一个TTask.Run。。
TTask.Run(cpro);
end; //但是其实,我倒是感觉这个TTask可以直接包在外面而不是包在里面,如果包在里面的话,我得用3个同样的代码块,而包在外面,里面用if-else的话,应该会简便一些代码……
end;
end;
好了,要说的代码其实也就只有这么点点,当我们点击刷新账号的按钮,然后点击保存并退出之后,我们就可以将新的AccessToken颁发给玩家用于启动游戏啦!!
还是那句老话,如果大家想在启动游戏时自动为玩家重置,大家大可以自行查询wiki,我就不多说了!好的咩!
2023.8.26解释:
鬼知道当初我为什么在前面声明三个bool变量,原来当初的我啥也不会啊……