Passed
Push — master ( dce7e6...e2e6ab )
by Vincent
06:59 queued 12s
created

name()   A

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 1
cts 1
cp 1
crap 1
rs 10
eloc 3
1
/*
2
 * This file is part of Araknemu.
3
 *
4
 * Araknemu is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU Lesser General Public License as published by
6
 * the Free Software Foundation, either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * Araknemu is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public License
15
 * along with Araknemu.  If not, see <https://www.gnu.org/licenses/>.
16
 *
17
 * Copyright (c) 2017-2020 Vincent Quatrevieux
18
 */
19
20
package fr.quatrevieux.araknemu.game.exploration.npc.exchange;
21
22
import fr.quatrevieux.araknemu.core.event.EventsSubscriber;
23
import fr.quatrevieux.araknemu.core.event.Listener;
24
import fr.quatrevieux.araknemu.data.world.entity.environment.npc.NpcExchange;
25
import fr.quatrevieux.araknemu.data.world.entity.environment.npc.NpcTemplate;
26
import fr.quatrevieux.araknemu.data.world.entity.item.ItemTemplate;
27
import fr.quatrevieux.araknemu.data.world.repository.environment.npc.NpcExchangeRepository;
28
import fr.quatrevieux.araknemu.data.world.repository.item.ItemTemplateRepository;
29
import fr.quatrevieux.araknemu.game.PreloadableService;
30
import fr.quatrevieux.araknemu.game.event.GameStarted;
31
import fr.quatrevieux.araknemu.game.exploration.npc.ExchangeProvider;
32
import fr.quatrevieux.araknemu.game.item.ItemService;
33
import org.apache.logging.log4j.Logger;
34
import org.checkerframework.checker.index.qual.Positive;
35
36
import java.util.HashMap;
37
import java.util.List;
38
import java.util.Map;
39
import java.util.Optional;
40
import java.util.concurrent.ConcurrentHashMap;
41
import java.util.stream.Collectors;
42
43
/**
44
 * Manage the npc exchanges
45
 */
46
public final class NpcExchangeService implements PreloadableService, EventsSubscriber, ExchangeProvider {
47
    private final ItemService itemService;
48
    private final NpcExchangeRepository repository;
49
    private final ItemTemplateRepository templateRepository;
50
51 1
    private final Map<Integer, GameNpcExchange> exchangeByTemplateId = new ConcurrentHashMap<>();
52 1
    private boolean preloading = false;
53
54 1
    public NpcExchangeService(ItemService itemService, NpcExchangeRepository repository, ItemTemplateRepository templateRepository) {
55 1
        this.itemService = itemService;
56 1
        this.repository = repository;
57 1
        this.templateRepository = templateRepository;
58 1
    }
59
60
    @Override
61
    public void preload(Logger logger) {
62 1
        preloading = true;
63 1
        logger.info("Loading npc exchanges...");
64
65 1
        repository.all().stream()
66 1
            .collect(Collectors.groupingBy(NpcExchange::npcTemplateId))
67 1
            .values()
68 1
            .forEach(this::createNpcExchange)
69
        ;
70
71 1
        logger.info("{} npc exchanges loaded", exchangeByTemplateId.size());
72 1
    }
73
74
    @Override
75
    public String name() {
76 1
        return "npc.exchange";
77
    }
78
79
    @Override
80
    public Listener[] listeners() {
81 1
        return new Listener[] {
82 1
            new Listener<GameStarted>() {
83
                @Override
84
                public void on(GameStarted event) {
85
                    preloading = false;
86
                }
87
88
                @Override
89
                public Class<GameStarted> event() {
90 1
                    return GameStarted.class;
91
                }
92
            },
93
        };
94
    }
95
96
    @Override
97
    public Optional<GameNpcExchange> load(NpcTemplate template) {
98 1
        final GameNpcExchange loadedExchange = exchangeByTemplateId.get(template.id());
99
100 1
        if (loadedExchange != null) {
101 1
            return Optional.of(loadedExchange);
102
        }
103
104
        // All exchanges are preloaded, but not found for the given npc
105
        // => the npc do not have exchange
106 1
        if (preloading) {
107
            return Optional.empty();
108
        }
109
110
        // Try loading from database
111 1
        final List<NpcExchange> exchangeEntities = repository.byNpcTemplate(template);
112
113 1
        if (exchangeEntities.isEmpty()) {
114 1
            return Optional.empty();
115
        }
116
117 1
        return Optional.of(createNpcExchange(exchangeEntities));
118
    }
119
120
    /**
121
     * Load the item template map
122
     */
123
    private Map<ItemTemplate, @Positive Integer> loadItemTemplates(Map<Integer, @Positive Integer> templateIdsAndQuantity) {
124 1
        final Map<ItemTemplate, @Positive Integer> templates = new HashMap<>(templateIdsAndQuantity.size());
125
126
        // @todo templateRepository#getAll
0 ignored issues
show
introduced by
Comment matches to-do format '(TODO:)|(@todo )'.
Loading history...
127 1
        templateIdsAndQuantity.forEach((templateId, quantity) -> templates.put(templateRepository.get(templateId), quantity));
128
129 1
        return templates;
130
    }
131
132
    /**
133
     * Creates the exchange from exchange entities
134
     */
135
    private GameNpcExchange createNpcExchange(List<NpcExchange> exchangeEntities) {
136 1
        final GameNpcExchange exchange = new GameNpcExchange(
137 1
            exchangeEntities.stream()
138 1
                .map(entity -> new NpcExchangeEntry(itemService, entity, loadItemTemplates(entity.exchangedItems())))
139 1
                .collect(Collectors.toList())
140
        );
141
142 1
        exchangeByTemplateId.put(exchangeEntities.get(0).npcTemplateId(), exchange);
143
144 1
        return exchange;
145
    }
146
}
147