aboutsummaryrefslogtreecommitdiff
path: root/src/modchannels.h
blob: 735609b59e91615032454516300616b21c62282d (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
84
85
86
87
88
89
90
91
92
93
/*
Minetest
Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#pragma once

#include <unordered_map>
#include <string>
#include <vector>
#include <memory>
#include "network/networkprotocol.h"
#include "irrlichttypes.h"

enum ModChannelState : u8
{
	MODCHANNEL_STATE_INIT,
	MODCHANNEL_STATE_READ_WRITE,
	MODCHANNEL_STATE_READ_ONLY,
	MODCHANNEL_STATE_MAX,
};

class ModChannel
{
public:
	ModChannel(const std::string &name) : m_name(name) {}
	~ModChannel() = default;

	const std::string &getName() const { return m_name; }
	bool registerConsumer(session_t peer_id);
	bool removeConsumer(session_t peer_id);
	const std::vector<u16> &getChannelPeers() const { return m_client_consumers; }
	bool canWrite() const;
	void setState(ModChannelState state);

private:
	std::string m_name;
	ModChannelState m_state = MODCHANNEL_STATE_INIT;
	std::vector<u16> m_client_consumers;
};

enum ModChannelSignal : u8
{
	MODCHANNEL_SIGNAL_JOIN_OK,
	MODCHANNEL_SIGNAL_JOIN_FAILURE,
	MODCHANNEL_SIGNAL_LEAVE_OK,
	MODCHANNEL_SIGNAL_LEAVE_FAILURE,
	MODCHANNEL_SIGNAL_CHANNEL_NOT_REGISTERED,
	MODCHANNEL_SIGNAL_SET_STATE,
};

class ModChannelMgr
{
public:
	ModChannelMgr() = default;
	~ModChannelMgr() = default;

	void registerChannel(const std::string &channel);
	bool setChannelState(const std::string &channel, ModChannelState state);
	bool joinChannel(const std::string &channel, session_t peer_id);
	bool leaveChannel(const std::string &channel, session_t peer_id);
	bool channelRegistered(const std::string &channel) const;
	ModChannel *getModChannel(const std::string &channel);
	/**
	 * This function check if a local mod can write on the channel
	 *
	 * @param channel
	 * @return true if write is allowed
	 */
	bool canWriteOnChannel(const std::string &channel) const;
	void leaveAllChannels(session_t peer_id);
	const std::vector<u16> &getChannelPeers(const std::string &channel) const;

private:
	bool removeChannel(const std::string &channel);

	std::unordered_map<std::string, std::unique_ptr<ModChannel>>
			m_registered_channels;
};
pan class="hl str">" "blarg = \"\"\" \n" "some multiline text\n" " with leading whitespace!\n" "\"\"\"\n" "np_terrain = 5, 40, (250, 250, 250), 12341, 5, 0.7, 2.4\n" "zoop = true"; const char *TestSettings::config_text_after = "leet = 1337\n" "leetleet = 13371337\n" "leetleet_neg = -13371337\n" "floaty_thing = 1.1\n" "stringy_thing = asd /( ¤%&(/\" BLÖÄRP\n" "coord = (1, 2, 4.5)\n" " # this is just a comment\n" "this is an invalid line\n" "asdf = {\n" " a = 5\n" " bb = 2.5\n" " ccc = \"\"\"\n" "testy\n" " testa \n" "\"\"\"\n" "\n" "}\n" "blarg = \"\"\" \n" "some multiline text\n" " with leading whitespace!\n" "\"\"\"\n" "np_terrain = {\n" " flags = defaults\n" " lacunarity = 2.4\n" " octaves = 6\n" " offset = 3.5\n" " persistence = 0.7\n" " scale = 40\n" " seed = 12341\n" " spread = (250,250,250)\n" "}\n" "zoop = true\n" "coord2 = (1,2,3.3)\n" "floaty_thing_2 = 1.2\n" "groupy_thing = {\n" " animals = cute\n" " num_apples = 4\n" " num_oranges = 53\n" "}\n"; void TestSettings::testAllSettings() { try { Settings s; // Test reading of settings std::istringstream is(config_text_before); s.parseConfigLines(is); UASSERT(s.getS32("leet") == 1337); UASSERT(s.getS16("leetleet") == 32767); UASSERT(s.getS16("leetleet_neg") == -32768); // Not sure if 1.1 is an exact value as a float, but doesn't matter UASSERT(fabs(s.getFloat("floaty_thing") - 1.1) < 0.001); UASSERT(s.get("stringy_thing") == "asd /( ¤%&(/\" BLÖÄRP"); UASSERT(fabs(s.getV3F("coord").X - 1.0) < 0.001); UASSERT(fabs(s.getV3F("coord").Y - 2.0) < 0.001); UASSERT(fabs(s.getV3F("coord").Z - 4.5) < 0.001); // Test the setting of settings too s.setFloat("floaty_thing_2", 1.2); s.setV3F("coord2", v3f(1, 2, 3.3)); UASSERT(s.get("floaty_thing_2").substr(0,3) == "1.2"); UASSERT(fabs(s.getFloat("floaty_thing_2") - 1.2) < 0.001); UASSERT(fabs(s.getV3F("coord2").X - 1.0) < 0.001); UASSERT(fabs(s.getV3F("coord2").Y - 2.0) < 0.001); UASSERT(fabs(s.getV3F("coord2").Z - 3.3) < 0.001); // Test settings groups Settings *group = s.getGroup("asdf"); UASSERT(group != NULL); UASSERT(s.getGroupNoEx("zoop", group) == false); UASSERT(group->getS16("a") == 5); UASSERT(fabs(group->getFloat("bb") - 2.5) < 0.001); Settings *group3 = new Settings; group3->set("cat", "meow"); group3->set("dog", "woof"); Settings *group2 = new Settings; group2->setS16("num_apples", 4); group2->setS16("num_oranges", 53); group2->setGroup("animals", group3); group2->set("animals", "cute"); //destroys group 3 s.setGroup("groupy_thing", group2); // Test set failure conditions UASSERT(s.set("Zoop = Poop\nsome_other_setting", "false") == false); UASSERT(s.set("sneaky", "\"\"\"\njabberwocky = false") == false); UASSERT(s.set("hehe", "asdfasdf\n\"\"\"\nsomething = false") == false); // Test multiline settings UASSERT(group->get("ccc") == "testy\n testa "); UASSERT(s.get("blarg") == "some multiline text\n" " with leading whitespace!"); // Test NoiseParams UASSERT(s.getEntry("np_terrain").is_group == false); NoiseParams np; UASSERT(s.getNoiseParams("np_terrain", np) == true); UASSERT(fabs(np.offset - 5) < 0.001); UASSERT(fabs(np.scale - 40) < 0.001); UASSERT(fabs(np.spread.X - 250) < 0.001); UASSERT(fabs(np.spread.Y - 250) < 0.001); UASSERT(fabs(np.spread.Z - 250) < 0.001); UASSERT(np.seed == 12341); UASSERT(np.octaves == 5); UASSERT(fabs(np.persist - 0.7) < 0.001); np.offset = 3.5; np.octaves = 6; s.setNoiseParams("np_terrain", np); UASSERT(s.getEntry("np_terrain").is_group == true); // Test writing std::ostringstream os(std::ios_base::binary); is.clear(); is.seekg(0); UASSERT(s.updateConfigObject(is, os, "", 0) == true); //printf(">>>> expected config:\n%s\n", TEST_CONFIG_TEXT_AFTER); //printf(">>>> actual config:\n%s\n", os.str().c_str()); UASSERT(os.str() == config_text_after); } catch (SettingNotFoundException &e) { UASSERT(!"Setting not found!"); } }