Fix bug #158 - Added plugin for setting topic (hub description).
Load plugin mod_topic, and it will provide 3 new user commands: !topic - set new topic !cleartopic - reset the topic (use default hub description) !showtopic - show the current topic
This commit is contained in:
parent
df7bbc094f
commit
1dba731cc3
|
@ -232,6 +232,9 @@ plugin_chat_history_TARGET := mod_chat_history.so
|
|||
plugin_chat_only_SOURCE := src/plugins/mod_chat_only.c
|
||||
plugin_chat_only_TARGET := mod_chat_only.so
|
||||
|
||||
plugin_topic_SOURCES := src/plugins/mod_topic.c
|
||||
plugin_topic_TARGET := mod_topic.so
|
||||
|
||||
# Source to objects
|
||||
libuhub_OBJECTS := $(libuhub_SOURCES:.c=.o)
|
||||
libutils_OBJECTS := $(libutils_SOURCES:.c=.o)
|
||||
|
@ -243,7 +246,7 @@ uhub-passwd_OBJECTS := $(uhub-passwd_SOURCES:.c=.o)
|
|||
adcrush_OBJECTS := $(adcrush_SOURCES:.c=.o)
|
||||
admin_OBJECTS := $(admin_SOURCES:.c=.o)
|
||||
|
||||
all_plugins := $(plugin_example_TARGET) $(plugin_logging_TARGET) $(plugin_auth_TARGET) $(plugin_auth_sqlite_TARGET) $(plugin_welcome_TARGET) $(plugin_chat_history_TARGET) $(plugin_chat_only_TARGET)
|
||||
all_plugins := $(plugin_example_TARGET) $(plugin_logging_TARGET) $(plugin_auth_TARGET) $(plugin_auth_sqlite_TARGET) $(plugin_welcome_TARGET) $(plugin_chat_history_TARGET) $(plugin_chat_only_TARGET) $(plugin_topic_TARGET)
|
||||
all_OBJECTS := $(libuhub_OBJECTS) $(uhub_OBJECTS) $(libutils_OBJECTS) $(adcrush_OBJECTS) $(autotest_OBJECTS) $(admin_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS)
|
||||
all_OBJECTS += $(all_plugins)
|
||||
|
||||
|
@ -289,6 +292,10 @@ $(plugin_chat_only_TARGET): $(plugin_chat_only_SOURCE) $(libutils_OBJECTS)
|
|||
$(plugin_welcome_TARGET): $(plugin_welcome_SOURCES) $(libutils_OBJECTS)
|
||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
||||
|
||||
$(plugin_topic_TARGET): $(plugin_topic_SOURCES) $(libutils_OBJECTS)
|
||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
||||
|
||||
|
||||
$(adcrush_BINARY): $(adcrush_OBJECTS) $(libuhub_OBJECTS) $(libutils_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS)
|
||||
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
|
||||
|
||||
|
|
|
@ -148,8 +148,11 @@ static enum command_parse_status command_extract_arguments(struct command_base*
|
|||
{
|
||||
int arg = 0;
|
||||
int opt = 0;
|
||||
int greedy = 0;
|
||||
char arg_code;
|
||||
char* token = NULL;
|
||||
char* tmp = NULL;
|
||||
size_t size = 0;
|
||||
struct hub_command_arg_data* data = NULL;
|
||||
enum command_parse_status status = cmd_status_ok;
|
||||
|
||||
|
@ -159,8 +162,28 @@ static enum command_parse_status command_extract_arguments(struct command_base*
|
|||
hub_free(token);
|
||||
|
||||
while (status == cmd_status_ok && (arg_code = command->args[arg++]))
|
||||
{
|
||||
if (greedy)
|
||||
{
|
||||
size = 1;
|
||||
for (tmp = (char*) list_get_first(tokens); tmp; tmp = (char*) list_get_next(tokens))
|
||||
size += (strlen(tmp) + 1);
|
||||
token = hub_malloc_zero(size);
|
||||
|
||||
while ((tmp = list_get_first(tokens)))
|
||||
{
|
||||
if (*token)
|
||||
strcat(token, " ");
|
||||
strcat(token, tmp);
|
||||
list_remove(tokens, tmp);
|
||||
hub_free(tmp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
token = list_get_first(tokens);
|
||||
}
|
||||
|
||||
if (!token || !*token)
|
||||
{
|
||||
status = (arg_code == '?' ? cmd_status_ok : cmd_status_missing_args);
|
||||
|
@ -173,6 +196,10 @@ static enum command_parse_status command_extract_arguments(struct command_base*
|
|||
opt = 1;
|
||||
continue;
|
||||
|
||||
case '+':
|
||||
greedy = 1;
|
||||
continue;
|
||||
|
||||
case 'u':
|
||||
data = hub_malloc(sizeof(*data));
|
||||
data->type = type_user;
|
||||
|
|
|
@ -128,12 +128,16 @@ extern struct hub_command_arg_data* hub_command_arg_next(struct hub_command* cmd
|
|||
* N = number (integer)
|
||||
*
|
||||
* Prefix an argument with ? to make it optional.
|
||||
* NOTE; if an argument is optional then all following arguments must also be optional.
|
||||
* Prefix with + to make the argument greedy, which causes it to grab the rest of the line ignoring boundaries (only supported for string types).
|
||||
*
|
||||
* NOTE: if an argument is optional then all following arguments must also be optional.
|
||||
* NOTE: You can combine optional and greedy, example: "?+m" would match "", "a", "a b c", etc.
|
||||
*
|
||||
* Example:
|
||||
* "nia" means "nick cid ip"
|
||||
* "n?p" means "nick [password]" where password is optional.
|
||||
*
|
||||
* "?N?N" means two optional integers, this can also be expressed as "?NN".
|
||||
* "?+m" means an optional string which may contain spaces that would otherwise be split into separate arguments.
|
||||
*/
|
||||
struct command_handle
|
||||
{
|
||||
|
|
|
@ -159,6 +159,58 @@ struct plugin_command_arg_data* cbfunc_command_arg_next(struct plugin_handle* pl
|
|||
return (struct plugin_command_arg_data*) hub_command_arg_next((struct hub_command*) cmd, (enum hub_command_arg_type) t);
|
||||
}
|
||||
|
||||
static char* cbfunc_get_hub_name(struct plugin_handle* plugin)
|
||||
{
|
||||
struct hub_info* hub = plugin_get_hub(plugin);
|
||||
char* str_encoded = adc_msg_get_named_argument(hub->command_info, ADC_INF_FLAG_NICK);
|
||||
char* str = adc_msg_unescape(str_encoded);
|
||||
hub_free(str_encoded);
|
||||
return str;
|
||||
}
|
||||
|
||||
static char* cbfunc_get_hub_description(struct plugin_handle* plugin)
|
||||
{
|
||||
struct hub_info* hub = plugin_get_hub(plugin);
|
||||
char* str_encoded = adc_msg_get_named_argument(hub->command_info, ADC_INF_FLAG_DESCRIPTION);
|
||||
char* str = adc_msg_unescape(str_encoded);
|
||||
hub_free(str_encoded);
|
||||
return str;
|
||||
}
|
||||
|
||||
static void cbfunc_set_hub_name(struct plugin_handle* plugin, const char* str)
|
||||
{
|
||||
struct hub_info* hub = plugin_get_hub(plugin);
|
||||
struct adc_message* command;
|
||||
char* new_str = adc_msg_escape(str ? str : hub->config->hub_name);
|
||||
|
||||
adc_msg_replace_named_argument(hub->command_info, ADC_INF_FLAG_NICK, new_str);
|
||||
|
||||
// Broadcast hub name
|
||||
command = adc_msg_construct(ADC_CMD_IINF, (strlen(new_str) + 8));
|
||||
adc_msg_add_named_argument(command, ADC_INF_FLAG_NICK, new_str);
|
||||
route_to_all(hub, command);
|
||||
|
||||
adc_msg_free(command);
|
||||
hub_free(new_str);
|
||||
}
|
||||
|
||||
static void cbfunc_set_hub_description(struct plugin_handle* plugin, const char* str)
|
||||
{
|
||||
struct hub_info* hub = plugin_get_hub(plugin);
|
||||
struct adc_message* command;
|
||||
char* new_str = adc_msg_escape(str ? str : hub->config->hub_description);
|
||||
|
||||
adc_msg_replace_named_argument(hub->command_info, ADC_INF_FLAG_DESCRIPTION, new_str);
|
||||
|
||||
// Broadcast hub description
|
||||
command = adc_msg_construct(ADC_CMD_IINF, (strlen(new_str) + 8));
|
||||
adc_msg_add_named_argument(command, ADC_INF_FLAG_DESCRIPTION, new_str);
|
||||
route_to_all(hub, command);
|
||||
|
||||
adc_msg_free(command);
|
||||
hub_free(new_str);
|
||||
}
|
||||
|
||||
void plugin_register_callback_functions(struct plugin_handle* handle)
|
||||
{
|
||||
handle->hub.send_message = cbfunc_send_message;
|
||||
|
@ -168,6 +220,10 @@ void plugin_register_callback_functions(struct plugin_handle* handle)
|
|||
handle->hub.command_del = cbfunc_command_del;
|
||||
handle->hub.command_arg_reset = cbfunc_command_arg_reset;
|
||||
handle->hub.command_arg_next = cbfunc_command_arg_next;
|
||||
handle->hub.get_name = cbfunc_get_hub_name;
|
||||
handle->hub.set_name = cbfunc_set_hub_name;
|
||||
handle->hub.get_description = cbfunc_get_hub_description;
|
||||
handle->hub.set_description = cbfunc_set_hub_description;
|
||||
}
|
||||
|
||||
void plugin_unregister_callback_functions(struct plugin_handle* handle)
|
||||
|
|
|
@ -118,6 +118,11 @@ typedef int (*hfunc_command_del)(struct plugin_handle*, struct plugin_command_ha
|
|||
typedef size_t (*hfunc_command_arg_reset)(struct plugin_handle*, struct plugin_command*);
|
||||
typedef struct plugin_command_arg_data* (*hfunc_command_arg_next)(struct plugin_handle*, struct plugin_command*, enum plugin_command_arg_type);
|
||||
|
||||
typedef char* (*hfunc_get_hub_name)(struct plugin_handle*);
|
||||
typedef char* (*hfunc_get_hub_description)(struct plugin_handle*);
|
||||
typedef void (*hfunc_set_hub_name)(struct plugin_handle*, const char*);
|
||||
typedef void (*hfunc_set_hub_description)(struct plugin_handle*, const char*);
|
||||
|
||||
/**
|
||||
* These are functions created and initialized by the hub and which can be used
|
||||
* by plugins to access functionality internal to the hub.
|
||||
|
@ -131,6 +136,10 @@ struct plugin_hub_funcs
|
|||
hfunc_command_del command_del;
|
||||
hfunc_command_arg_reset command_arg_reset;
|
||||
hfunc_command_arg_next command_arg_next;
|
||||
hfunc_get_hub_name get_name;
|
||||
hfunc_get_hub_description get_description;
|
||||
hfunc_set_hub_name set_name;
|
||||
hfunc_set_hub_description set_description;
|
||||
};
|
||||
|
||||
struct plugin_handle
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "plugin_api/handle.h"
|
||||
#include "plugin_api/command_api.h"
|
||||
#include "util/memory.h"
|
||||
#include "util/cbuffer.h"
|
||||
|
||||
struct topic_plugin_data
|
||||
{
|
||||
struct plugin_command_handle* topic;
|
||||
struct plugin_command_handle* cleartopic;
|
||||
struct plugin_command_handle* showtopic;
|
||||
};
|
||||
|
||||
static int command_topic_handler(struct plugin_handle* plugin, struct plugin_user* user, struct plugin_command* cmd)
|
||||
{
|
||||
struct cbuffer* buf = cbuf_create(128);
|
||||
struct plugin_command_arg_data* arg = plugin->hub.command_arg_next(plugin, cmd, plugin_cmd_arg_type_string);
|
||||
|
||||
plugin->hub.set_description(plugin, arg ? arg->data.string : NULL);
|
||||
cbuf_append_format(buf, "*** %s: Topic set to \"%s\"", cmd->prefix, arg->data.string);
|
||||
plugin->hub.send_message(plugin, user, cbuf_get(buf));
|
||||
cbuf_destroy(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int command_cleartopic_handler(struct plugin_handle* plugin, struct plugin_user* user, struct plugin_command* cmd)
|
||||
{
|
||||
struct cbuffer* buf = cbuf_create(128);
|
||||
plugin->hub.set_description(plugin, NULL);
|
||||
cbuf_append_format(buf, "*** %s: Topic cleared.", cmd->prefix);
|
||||
plugin->hub.send_message(plugin, user, cbuf_get(buf));
|
||||
cbuf_destroy(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int command_showtopic_handler(struct plugin_handle* plugin, struct plugin_user* user, struct plugin_command* cmd)
|
||||
{
|
||||
struct cbuffer* buf = cbuf_create(128);
|
||||
char* topic = plugin->hub.get_description(plugin);
|
||||
cbuf_append_format(buf, "*** %s: Current topic is: \"%s\"", cmd->prefix, topic);
|
||||
plugin->hub.send_message(plugin, user, cbuf_get(buf));
|
||||
cbuf_destroy(buf);
|
||||
hub_free(topic);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int plugin_register(struct plugin_handle* plugin, const char* config)
|
||||
{
|
||||
struct topic_plugin_data* data = (struct topic_plugin_data*) hub_malloc(sizeof(struct topic_plugin_data));
|
||||
|
||||
data->topic = (struct plugin_command_handle*) hub_malloc_zero(sizeof(struct plugin_command_handle));
|
||||
data->cleartopic = (struct plugin_command_handle*) hub_malloc_zero(sizeof(struct plugin_command_handle));
|
||||
data->showtopic = (struct plugin_command_handle*) hub_malloc_zero(sizeof(struct plugin_command_handle));
|
||||
|
||||
PLUGIN_INITIALIZE(plugin, "Topic plugin", "1.0", "Add commands for changing the hub topic (description)");
|
||||
|
||||
PLUGIN_COMMAND_INITIALIZE(data->topic, (void*) data, "topic", "+m", auth_cred_operator, command_topic_handler, "Set new topic");
|
||||
PLUGIN_COMMAND_INITIALIZE(data->cleartopic, (void*) data, "cleartopic", "", auth_cred_operator, command_cleartopic_handler, "Clear the current topic");
|
||||
PLUGIN_COMMAND_INITIALIZE(data->showtopic, (void*) data, "showtopic", "", auth_cred_guest, command_showtopic_handler, "Shows the current topic");
|
||||
|
||||
plugin->hub.command_add(plugin, data->topic);
|
||||
plugin->hub.command_add(plugin, data->cleartopic);
|
||||
plugin->hub.command_add(plugin, data->showtopic);
|
||||
plugin->ptr = data;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int plugin_unregister(struct plugin_handle* plugin)
|
||||
{
|
||||
struct topic_plugin_data* data = (struct topic_plugin_data*) plugin->ptr;
|
||||
|
||||
plugin->hub.command_del(plugin, data->topic);
|
||||
plugin->hub.command_del(plugin, data->cleartopic);
|
||||
plugin->hub.command_del(plugin, data->showtopic);
|
||||
hub_free(data->topic);
|
||||
hub_free(data->showtopic);
|
||||
hub_free(data);
|
||||
plugin->ptr = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{9BBAEFDA-8E0E-4E7F-B8B6-00A3432FC45B}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>mod_topic</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(SolutionDir)..\src;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(SolutionDir)vs2010\$(Configuration);$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXAMPLE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>$(SolutionDir)\$(Configuration)\uhub_utils.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXAMPLE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\src\plugins\mod_topic.c" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -32,6 +32,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "uhub-passwd", "uhub-passwd\
|
|||
{A4FC9D62-D544-4D2A-88D7-A58529C3460B} = {A4FC9D62-D544-4D2A-88D7-A58529C3460B}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_topic", "plugins\mod_topic\mod_topic.vcxproj", "{9BBAEFDA-8E0E-4E7F-B8B6-00A3432FC45B}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{0A3C1519-D877-47D9-A82E-40AC1BC79D75} = {0A3C1519-D877-47D9-A82E-40AC1BC79D75}
|
||||
{98D8BFE9-DACD-40E1-B7BE-C9079ABF832E} = {98D8BFE9-DACD-40E1-B7BE-C9079ABF832E}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
|
@ -66,6 +72,10 @@ Global
|
|||
{E92EB860-AE9E-4532-A75F-0929A7BCF6D0}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{E92EB860-AE9E-4532-A75F-0929A7BCF6D0}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{E92EB860-AE9E-4532-A75F-0929A7BCF6D0}.Release|Win32.Build.0 = Release|Win32
|
||||
{9BBAEFDA-8E0E-4E7F-B8B6-00A3432FC45B}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{9BBAEFDA-8E0E-4E7F-B8B6-00A3432FC45B}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{9BBAEFDA-8E0E-4E7F-B8B6-00A3432FC45B}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{9BBAEFDA-8E0E-4E7F-B8B6-00A3432FC45B}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
Loading…
Reference in New Issue