Официальная авторизация от моджанг

Версия Minecraft
1.0+
У меня есть исходники лаунчера SKcraft, с официальной авторизацией. Мне нужно лицензионную авторизацию переделать. Что бы входить надо было не в аккаунт от моджанга, а в аккаунт, созданный на моем сайте. Я понял, что нужно просто написать на сайте скрипт, который будет имитировать официальную авторизацию и в исходниках поменять ссылку со скрипта моджанга на мой скрипт. Вот только проблема. Я не знаю, что должен возвращать скрипт. Копался в исходниках лаунчера, так и не разобрался, что он требует от скрипта(я не знаю java, по этому и не разобрался). Кто знает, как это работает? Скажите пожалуйста, что должен вернуть скрипт и в каком формате? PS сори за вопрос не по теме.
 

jopi

Попрошайка
1,421
30
260
У меня есть исходники лаунчера SKcraft, с официальной авторизацией. Мне нужно лицензионную авторизацию переделать. Что бы входить надо было не в аккаунт от моджанга, а в аккаунт, созданный на моем сайте. Я понял, что нужно просто написать на сайте скрипт, который будет имитировать официальную авторизацию и в исходниках поменять ссылку со скрипта моджанга на мой скрипт. Вот только проблема. Я не знаю, что должен возвращать скрипт. Копался в исходниках лаунчера, так и не разобрался, что он требует от скрипта(я не знаю java, по этому и не разобрался). Кто знает, как это работает? Скажите пожалуйста, что должен вернуть скрипт и в каком формате? PS сори за вопрос не по теме.
лол, попробуй сделать на sashok, там должно получится если ты яву не знаешь
 

Icosider

Kotliner
Администратор
3,603
99
664
У меня есть исходники лаунчера SKcraft, с официальной авторизацией. Мне нужно лицензионную авторизацию переделать. Что бы входить надо было не в аккаунт от моджанга, а в аккаунт, созданный на моем сайте. Я понял, что нужно просто написать на сайте скрипт, который будет имитировать официальную авторизацию и в исходниках поменять ссылку со скрипта моджанга на мой скрипт. Вот только проблема. Я не знаю, что должен возвращать скрипт. Копался в исходниках лаунчера, так и не разобрался, что он требует от скрипта(я не знаю java, по этому и не разобрался). Кто знает, как это работает? Скажите пожалуйста, что должен вернуть скрипт и в каком формате? PS сори за вопрос не по теме.
Начнём с того, чтобы сделать свою авторизацию, нужно изменить Authlib, написать скрипт, отправлять из лаунчера данные в скрипт на сайте, а скрипт должен проверить есть ли такой игрок, правильный ли пароль, и т.д.
 
Начнём с того, чтобы сделать свою авторизацию, нужно изменить Authlib, написать скрипт, отправлять из лаунчера данные в скрипт на сайте, а скрипт должен проверить есть ли такой игрок, правильный ли пароль, и т.д.
Я же написал, что у меня уже есть ихсодники лаунчера. там уже все есть. В лаунчере мне нужно только изменить ссылку на скрипт авторизации, что я сделал
 
Начнём с того, чтобы сделать свою авторизацию, нужно изменить Authlib, написать скрипт, отправлять из лаунчера данные в скрипт на сайте, а скрипт должен проверить есть ли такой игрок, правильный ли пароль, и т.д.
Он сам уже все отправляет. мне нужно написать php скрипт, который будет обрабатывать данные, которые прислал лаунчер и давать ему ответ. А я не знаю что и как скрипт должен должен возвращать лаунчеру
 

Icosider

Kotliner
Администратор
3,603
99
664
Он сам уже все отправляет. мне нужно написать php скрипт, который будет обрабатывать данные, которые прислал лаунчер и давать ему ответ. А я не знаю что и как скрипт должен должен возвращать лаунчеру
Это по части веба, если не разбираешься то не лезь. Здесь форум по моддингу, а не помощь в написание веб скриптов. И я тебе уже сказал что нужно делать.
 

Icosider

Kotliner
Администратор
3,603
99
664
На самом деле, был уже туториал про даже скрипты. По-моему
Да? Не видел. Автор темы не в курсе, что такие скрипты нужно писать самому под свою CMS или фреймворк(тут уже проще, так как всё своё).
 

Icosider

Kotliner
Администратор
3,603
99
664
Не очень сложно. Достаточно базу данных иметь, куда можно будет токен писать. Может быть, есть возможность замутить что-то с OAuth. Я в вебе не шарю, но делал такое когда-то.
Если своя авторизация, то и оаутх прикрутить не проблема. Я мейби в джава не шарю, зато в вебе)
 

CumingSoon

Местный стендапер
1,634
12
269
На пышечке не так уж и сложно писать. Так что ОП спокойно может сделать то, что хочет. Нужно только мозги сломать с токенами и с порядком отправки сообщений. У меня ушло полгода, но я был тогда маленьким, глупым. Пусть ищет тутор taogunner'a
 

Icosider

Kotliner
Администратор
3,603
99
664
На пышечке не так уж и сложно писать. Так что ОП спокойно может сделать то, что хочет. Нужно только мозги сломать с токенами и с порядком отправки сообщений. У меня ушло полгода, но я был тогда маленьким, глупым. Пусть ищет тутор taogunner'a
Пышка калл ;) Уже перешел на питона. Порядком отправки сообщений? Я чего то не знаю?)
 
Это по части веба, если не разбираешься то не лезь. Здесь форум по моддингу, а не помощь в написание веб скриптов. И я тебе уже сказал что нужно делать.
По части веба как раз-таки я шарю.
 
Это по части веба, если не разбираешься то не лезь. Здесь форум по моддингу, а не помощь в написание веб скриптов. И я тебе уже сказал что нужно делать.
лаунчер требует определенны ответ, в определенном формате. Если я просто сделаю так, что php ответит "OK" ничего не заработает. я не спрашиваю что мне писать в скрипте., я спрашиваю, как работает официальная авторизация и что она отвечает при запросе к ней. Так сложно понять, что я спрашиваю?
 

Icosider

Kotliner
Администратор
3,603
99
664
лаунчер требует определенны ответ, в определенном формате. Если я просто сделаю так, что php ответит "OK" ничего не заработает. я не спрашиваю что мне писать в скрипте., я спрашиваю, как работает официальная авторизация и что она отвечает при запросе к ней. Так сложно понять, что я спрашиваю?
Мы не ванги, мы не можем знать что именно твой лаунчер хочет получить в ответ. Авторизация в мк проходит через два файла, какие именно уже не помню. На руведре в теме со старым сашком, alexandrage выкладывал эти файлы в облако. Смотри, изучай, и на сколько я знаю с 1.7.10 без вмешательства в аутлибу у тебя мало что выйдет.

Ноу-хау. Секрет на миллион долларов
Алсо, питон кал
Лол, а чем тебе питон не угодил?) Или это так, рофл?)) Я по началу думал на руби перейти, но не стал из-за его грамосткости в некоторых вещах(да да, у питона тоже такие есть). Но питом прям реально дает развернуться. Тоже выполнение из под консоли чего стоит(это уже если не про веб).
 
Мы не ванги, мы не можем знать что именно твой лаунчер хочет получить в ответ. Авторизация в мк проходит через два файла, какие именно уже не помню. На руведре в теме со старым сашком, alexandrage выкладывал эти файлы в облако. Смотри, изучай, и на сколько я знаю с 1.7.10 без вмешательства в аутлибу у тебя мало что выйдет.


Лол, а чем тебе питон не угодил?) Или это так, рофл?)) Я по началу думал на руби перейти, но не стал из-за его грамосткости в некоторых вещах(да да, у питона тоже такие есть). Но питом прям реально дает развернуться. Тоже выполнение из под консоли чего стоит(это уже если не про веб).
Там официальная афторизация от моджанга. Игдрасиль вроде называется. Она везде одинаковая. А я хочу узнать, как она работает.
 
Последнее редактирование:

Icosider

Kotliner
Администратор
3,603
99
664
А я хочу узнать, как она работает
Мля, как и все остальные авторизации, только у моджанг всё через аргументы(кроме пассворда или он там шифруется, точно не помню). Лаунчер отправляет запрос на сайт, сайт ему отвечает что мол такой игрок есть и пароль верен, аутхлиба добавляет два аргумента и всё, ты заходишь. Про серверную аутхлибу рассказывать не буду.
Если нужно изменить авторизацию в майне на свою(online-mode: true) то изменяешь этот класс и ещё один в той же папке:
Java:
public class YggdrasilMinecraftSessionService extends HttpMinecraftSessionService {
    private static final String[] WHITELISTED_DOMAINS = {
        ".minecraft.net",
        ".mojang.com"
    };
    private static final Logger LOGGER = LogManager.getLogger();
    private static final String BASE_URL = "https://sessionserver.mojang.com/session/minecraft/";
    private static final URL JOIN_URL = HttpAuthenticationService.constantURL(BASE_URL + "join");
    private static final URL CHECK_URL = HttpAuthenticationService.constantURL(BASE_URL + "hasJoined");

    private final PublicKey publicKey;
    private final Gson gson = new GsonBuilder().registerTypeAdapter(UUID.class, new UUIDTypeAdapter()).create();
    private final LoadingCache<GameProfile, GameProfile> insecureProfiles = CacheBuilder
        .newBuilder()
        .expireAfterWrite(6, TimeUnit.HOURS)
        .build(new CacheLoader<GameProfile, GameProfile>() {
            @Override
            public GameProfile load(final GameProfile key) throws Exception {
                return fillGameProfile(key, false);
            }
        });

    protected YggdrasilMinecraftSessionService(final YggdrasilAuthenticationService authenticationService) {
        super(authenticationService);

        try {
            final X509EncodedKeySpec spec = new X509EncodedKeySpec(IOUtils.toByteArray(YggdrasilMinecraftSessionService.class.getResourceAsStream("/yggdrasil_session_pubkey.der")));
            final KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            publicKey = keyFactory.generatePublic(spec);
        } catch (final Exception ignored) {
            throw new Error("Missing/invalid yggdrasil public key!");
        }
    }

    @Override
    public void joinServer(final GameProfile profile, final String authenticationToken, final String serverId) throws AuthenticationException {
        final JoinMinecraftServerRequest request = new JoinMinecraftServerRequest();
        request.accessToken = authenticationToken;
        request.selectedProfile = profile.getId();
        request.serverId = serverId;

        getAuthenticationService().makeRequest(JOIN_URL, request, Response.class);
    }

    @Override
    public GameProfile hasJoinedServer(final GameProfile user, final String serverId, final InetAddress address) throws AuthenticationUnavailableException {
        final Map<String, Object> arguments = new HashMap<String, Object>();

        arguments.put("username", user.getName());
        arguments.put("serverId", serverId);

        if (address != null) {
            arguments.put("ip", address.getHostAddress());
        }

        final URL url = HttpAuthenticationService.concatenateURL(CHECK_URL, HttpAuthenticationService.buildQuery(arguments));

        try {
            final HasJoinedMinecraftServerResponse response = getAuthenticationService().makeRequest(url, null, HasJoinedMinecraftServerResponse.class);

            if (response != null && response.getId() != null) {
                final GameProfile result = new GameProfile(response.getId(), user.getName());

                if (response.getProperties() != null) {
                    result.getProperties().putAll(response.getProperties());
                }

                return result;
            } else {
                return null;
            }
        } catch (final AuthenticationUnavailableException e) {
            throw e;
        } catch (final AuthenticationException ignored) {
            return null;
        }
    }

    @Override
    public Map<MinecraftProfileTexture.Type, MinecraftProfileTexture> getTextures(final GameProfile profile, final boolean requireSecure) {
        final Property textureProperty = Iterables.getFirst(profile.getProperties().get("textures"), null);

        if (textureProperty == null) {
            return new HashMap<MinecraftProfileTexture.Type, MinecraftProfileTexture>();
        }

        if (requireSecure) {
            if (!textureProperty.hasSignature()) {
                LOGGER.error("Signature is missing from textures payload");
                throw new InsecureTextureException("Signature is missing from textures payload");
            }

            if (!textureProperty.isSignatureValid(publicKey)) {
                LOGGER.error("Textures payload has been tampered with (signature invalid)");
                throw new InsecureTextureException("Textures payload has been tampered with (signature invalid)");
            }
        }

        final MinecraftTexturesPayload result;
        try {
            final String json = new String(Base64.decodeBase64(textureProperty.getValue()), Charsets.UTF_8);
            result = gson.fromJson(json, MinecraftTexturesPayload.class);
        } catch (final JsonParseException e) {
            LOGGER.error("Could not decode textures payload", e);
            return new HashMap<MinecraftProfileTexture.Type, MinecraftProfileTexture>();
        }

        if (result == null || result.getTextures() == null) {
            return new HashMap<MinecraftProfileTexture.Type, MinecraftProfileTexture>();
        }

        for (final Map.Entry<MinecraftProfileTexture.Type, MinecraftProfileTexture> entry : result.getTextures().entrySet()) {
            if (!isWhitelistedDomain(entry.getValue().getUrl())) {
                LOGGER.error("Textures payload has been tampered with (non-whitelisted domain)");
                return new HashMap<MinecraftProfileTexture.Type, MinecraftProfileTexture>();
            }
        }

        return result.getTextures();
    }

    @Override
    public GameProfile fillProfileProperties(final GameProfile profile, final boolean requireSecure) {
        if (profile.getId() == null) {
            return profile;
        }

        if (!requireSecure) {
            return insecureProfiles.getUnchecked(profile);
        }

        return fillGameProfile(profile, true);
    }

    protected GameProfile fillGameProfile(final GameProfile profile, final boolean requireSecure) {
        try {
            URL url = HttpAuthenticationService.constantURL(BASE_URL + "profile/" + UUIDTypeAdapter.fromUUID(profile.getId()));
            url = HttpAuthenticationService.concatenateURL(url, "unsigned=" + !requireSecure);
            final MinecraftProfilePropertiesResponse response = getAuthenticationService().makeRequest(url, null, MinecraftProfilePropertiesResponse.class);

            if (response == null) {
                LOGGER.debug("Couldn't fetch profile properties for " + profile + " as the profile does not exist");
                return profile;
            } else {
                final GameProfile result = new GameProfile(response.getId(), response.getName());
                result.getProperties().putAll(response.getProperties());
                profile.getProperties().putAll(response.getProperties());
                LOGGER.debug("Successfully fetched profile properties for " + profile);
                return result;
            }
        } catch (final AuthenticationException e) {
            LOGGER.warn("Couldn't look up profile properties for " + profile, e);
            return profile;
        }
    }

    @Override
    public YggdrasilAuthenticationService getAuthenticationService() {
        return (YggdrasilAuthenticationService) super.getAuthenticationService();
    }

    private static boolean isWhitelistedDomain(final String url) {
        URI uri = null;

        try {
            uri = new URI(url);
        } catch (final URISyntaxException ignored) {
            throw new IllegalArgumentException("Invalid URL '" + url + "'");
        }

        final String domain = uri.getHost();

        for (int i = 0; i < WHITELISTED_DOMAINS.length; i++) {
            if (domain.endsWith(WHITELISTED_DOMAINS[i])) {
                return true;
            }
        }
        return false;
    }
}
И говорю сразу, С 1.7.10 нельзя больше тупо изменить ссылку на авторизацию и всё успешно заработает!
 
Сверху