aboutsummaryrefslogtreecommitdiff
path: root/diplomacy/web/src/gui/utils/load_game_from_disk.js
blob: ca49aa08c61e54b46d7d86022b4d2e7845df6e44 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import $ from "jquery";
import {STRINGS} from "../../diplomacy/utils/strings";
import {Game} from "../../diplomacy/engine/game";

export function loadGameFromDisk(onLoad, onError) {
    const input = $(document.createElement('input'));
    input.attr("type", "file");
    input.trigger('click');
    input.change(event => {
        const file = event.target.files[0];
        if (!file.name.match(/\.json$/i)) {
            onError(`Invalid JSON filename ${file.name}`);
            return;
        }
        const reader = new FileReader();
        reader.onload = () => {
            const savedData = JSON.parse(reader.result);
            const gameObject = {};
            gameObject.game_id = `(local) ${savedData.id}`;
            gameObject.map_name = savedData.map;
            gameObject.rules = savedData.rules;
            gameObject.state_history = {};
            gameObject.message_history = {};
            gameObject.order_history = {};
            gameObject.result_history = {};

            // Load all saved phases (expect the latest one) to history fields.
            for (let i = 0; i < savedData.phases.length - 1; ++i) {
                const savedPhase = savedData.phases[i];
                const gameState = savedPhase.state;
                const phaseOrders = savedPhase.orders || {};
                const phaseResults = savedPhase.results || {};
                const phaseMessages = {};
                if (savedPhase.messages) {
                    for (let message of savedPhase.messages) {
                        phaseMessages[message.time_sent] = message;
                    }
                }
                if (!gameState.name)
                    gameState.name = savedPhase.name;
                gameObject.state_history[gameState.name] = gameState;
                gameObject.message_history[gameState.name] = phaseMessages;
                gameObject.order_history[gameState.name] = phaseOrders;
                gameObject.result_history[gameState.name] = phaseResults;
            }

            // Load latest phase separately and use it later to define the current game phase.
            const latestPhase = savedData.phases[savedData.phases.length - 1];
            const latestGameState = latestPhase.state;
            const latestPhaseOrders = latestPhase.orders || {};
            const latestPhaseResults = latestPhase.results || {};
            const latestPhaseMessages = {};
            if (latestPhase.messages) {
                for (let message of latestPhase.messages) {
                    latestPhaseMessages[message.time_sent] = message;
                }
            }
            if (!latestGameState.name)
                latestGameState.name = latestPhase.name;
            // TODO: NB: What is latest phase in loaded JSON contains order results? Not sure if it is well handled.
            gameObject.result_history[latestGameState.name] = latestPhaseResults;

            gameObject.messages = [];
            gameObject.role = STRINGS.OBSERVER_TYPE;
            gameObject.status = STRINGS.COMPLETED;
            gameObject.timestamp_created = 0;
            gameObject.deadline = 0;
            gameObject.n_controls = 0;
            gameObject.registration_password = '';
            const game = new Game(gameObject);

            // Set game current phase and state using latest phase found in JSON file.
            game.setPhaseData({
                name: latestGameState.name,
                state: latestGameState,
                orders: latestPhaseOrders,
                messages: latestPhaseMessages
            });
            onLoad(game);
        };
        reader.readAsText(file);
    });
}