|  | 
 
| 
本帖最后由 WisW 于 2025-1-28 23:04 编辑
x
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册 
    
 瞎写的;
 
 我承认, 我一直对拿一个真正能登上游戏账号的token来验证正版持不满意的态度
 这意味着我的账号访问权限被放出去了24个小时(我承认比原先的不改密码就是永远好)
 
 好的, 新的正版验证是基于皮肤的验证, 流程如下: 请求论坛 -> 论坛返回一个随机皮肤 -> 玩家更改皮肤 -> 论坛验证 -> 完成
 这个服务应该压力不会太大: 需要发几个请求, 要有数据库; (我突然想到一个, 我们能不能用签名来干掉数据库, 应该是可以的, 玩家皮肤的数据量够了)
 
 最好的情况是我们找得到一个能用cloudflare worker的人, 这样能用一些基于nodejs的东西, 和discuz!联动也会方便一些
 我不认为直接在discuz!上写所有代码是一个好选择, 因为我不太确定它有没有图片处理的一些库, 而且时间成本会很高(对我来说)
 
 悲, 我寻思我已经不是那个可以无视时间成本的人了
 
 附一些我之前写的代码
 
 | const PNG = require('pngjs').PNG;
async function tick(env) {
  await env.MCDB.prepare(
        "DELETE FROM mc WHERE createTime < ?"
      )
      .bind(Date.now() - 2*300000)
      .run();
}
export async function getSession(playerName, env) {
  tick(env);
  let find = false
  let id = 0;
  while (!find) {
    id = Math.floor(Math.random()*2147483647);
    const { results } = await env.MCDB.prepare(
        "SELECT * FROM mc WHERE sessionId = ?"
      )
      .bind(id)
      .all();
      find = (results.length == 0);
  }
  let skin = "";
  let res;
  let req = new Request("https://api.mojang.com/users/profiles/minecraft/" + playerName);
  res = await fetch(req).then(response => response.json()).then(data => {
    return data;
  });
  req = new Request("https://sessionserver.mojang.com/session/minecraft/profile/" + res.id);
  res = await fetch(req).then(response => response.json()).then(data => {
    return data;
  });
  res = JSON.parse(atob(res.properties[0].value)).textures.SKIN.url;
  let response = await fetch(res);
  new PNG({ filterType: 4 }).parse(await response.arrayBuffer(), async function (error, data) {
    for (var i = 0; i < 64; i++) {
      for (var j = 0; j < 64; j++) {
        var idx = (64 * i + j) << 2;
        var x = data.data[idx];
        var y = data.data[idx + 1];
        var z = data.data[idx + 2];
        var a = data.data[idx + 3];
        if (i >= 8 || j >= 8) {
          if (x < 16) {
            skin += "0";
          }
          skin += x.toString(16);
          if (y < 16) {
            skin += "0";
          }
          skin += y.toString(16);
          if (z < 16) {
            skin += "0";
          }
          skin += z.toString(16);
          if (a < 16) {
            skin += "0";
          }
          skin += a.toString(16);
        } else {
          skin += Math.floor(Math.random()*16).toString(16);
          skin += Math.floor(Math.random()*16).toString(16);
          skin += Math.floor(Math.random()*16).toString(16);
          skin += Math.floor(Math.random()*16).toString(16);
          skin += Math.floor(Math.random()*16).toString(16);
          skin += Math.floor(Math.random()*16).toString(16);
          skin += "ff"
        }
    }
  }
  await env.MCDB.prepare(
      "INSERT INTO mc (sessionId, name, createTime, skin) VALUES (?, ?, ?, ?)"
    )
    .bind(id, playerName, Date.now(), skin)
    .run();
  });
  return id;
}
export async function getSkin(playerName, id, env) {
  tick(env);
  try {
    const { results } = await env.MCDB.prepare(
        "SELECT * FROM mc WHERE sessionId = ?"
      )
      .bind(id)
      .all();
    if (results[0].name != playerName) {
      return -1;
    }
    return results[0].skin;
  } catch(e) {
      return -1;
  }
  return -1;
}
export async function verify(playerName, id, env) {
  tick(env);
  const { results } = await env.MCDB.prepare(
        "SELECT * FROM mc WHERE sessionId = ?"
      )
      .bind(id)
      .all();
  if (results[0].name != playerName) {
    return -1;
  }
  const skinSt = results[0].skin;
  let res;
  let req = new Request("https://api.mojang.com/users/profiles/minecraft/" + playerName);
  res = await fetch(req).then(response => response.json()).then(data => {
    return data;
  });
  req = new Request("https://sessionserver.mojang.com/session/minecraft/profile/" + res.id);
  res = await fetch(req).then(response => response.json()).then(data => {
    return data;
  });
  res = JSON.parse(atob(res.properties[0].value)).textures.SKIN.url;
  let response = await fetch(res);
  new PNG({ filterType: 4 }).parse(await response.arrayBuffer(), function (error, data) {
    let counterSt = 0;
    let flag = true;
    for (var i = 0; i < 64; i++) {
      for (var j = 0; j < 64; j++) {
        var f = counterSt * 8;
        var a = parseInt(skinSt.substring(f, f + 2), 16);
        var b = parseInt(skinSt.substring(f + 2, f + 4), 16);
        var c = parseInt(skinSt.substring(f + 4, f + 6), 16);
        counterSt++;
        var idx = (64 * i + j) << 2;
        var x = data.data[idx];
        var y = data.data[idx + 1];
        var z = data.data[idx + 2];
        //console.log(a + " " + b + " " + c + " " + x + " " + y + " " + z);
        if (x != a || y != b || z != c) {
          flag = false;
          //console.log(a + " " + b + " " + c + " " + x + " " + y + " " + z + " pi " + i + " pj " + j);
          break;
        }
      }
      if (!flag) {
        break;
      }
    }
    if (flag) {
      env.MCDB.prepare(
        "UPDATE mc SET verify = '1' WHERE sessionId = ?"
      )
      .bind(results[0].sessionId)
      .run();
    }
  });
}
export async function getResult(playerName, id, env) {
  tick(env);
  try {
    const { results } = await env.MCDB.prepare(
        "SELECT * FROM mc WHERE sessionId = ?"
      )
      .bind(id)
      .all();
    if (results[0].name != playerName) {
      return false;
    }
    return results[0].verify;
  } catch(e) {
      return false;
  }
  return false;
}
 | 
 扔在这里, 有谁有能力的或许能实现罢
 
 | 
 |