This repository has been archived by the owner on Jul 16, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5c48b0d
commit 1876946
Showing
9 changed files
with
604 additions
and
0 deletions.
There are no files selected for viewing
167 changes: 167 additions & 0 deletions
167
samples/InteractiveScreenControlSample/InteractiveSample.vcxproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project DefaultTargets="Build" ToolsVersion="15.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> | ||
<ProjectConfiguration Include="Debug|x64"> | ||
<Configuration>Debug</Configuration> | ||
<Platform>x64</Platform> | ||
</ProjectConfiguration> | ||
<ProjectConfiguration Include="Release|x64"> | ||
<Configuration>Release</Configuration> | ||
<Platform>x64</Platform> | ||
</ProjectConfiguration> | ||
</ItemGroup> | ||
<PropertyGroup Label="Globals"> | ||
<VCProjectVersion>15.0</VCProjectVersion> | ||
<ProjectGuid>{C5D30411-CECD-48B1-9B9C-3C86A1ACD2FA}</ProjectGuid> | ||
<Keyword>Win32Proj</Keyword> | ||
<RootNamespace>InteractiveSample</RootNamespace> | ||
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> | ||
<ProjectName>InteractiveScreenControlSample</ProjectName> | ||
</PropertyGroup> | ||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | ||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> | ||
<ConfigurationType>Application</ConfigurationType> | ||
<UseDebugLibraries>true</UseDebugLibraries> | ||
<PlatformToolset>v141</PlatformToolset> | ||
<CharacterSet>Unicode</CharacterSet> | ||
</PropertyGroup> | ||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> | ||
<ConfigurationType>Application</ConfigurationType> | ||
<UseDebugLibraries>false</UseDebugLibraries> | ||
<PlatformToolset>v141</PlatformToolset> | ||
<WholeProgramOptimization>true</WholeProgramOptimization> | ||
<CharacterSet>Unicode</CharacterSet> | ||
</PropertyGroup> | ||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> | ||
<ConfigurationType>Application</ConfigurationType> | ||
<UseDebugLibraries>true</UseDebugLibraries> | ||
<PlatformToolset>v141</PlatformToolset> | ||
<CharacterSet>NotSet</CharacterSet> | ||
</PropertyGroup> | ||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> | ||
<ConfigurationType>Application</ConfigurationType> | ||
<UseDebugLibraries>false</UseDebugLibraries> | ||
<PlatformToolset>v141</PlatformToolset> | ||
<WholeProgramOptimization>true</WholeProgramOptimization> | ||
<CharacterSet>Unicode</CharacterSet> | ||
</PropertyGroup> | ||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | ||
<ImportGroup Label="ExtensionSettings"> | ||
</ImportGroup> | ||
<ImportGroup Label="Shared"> | ||
</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> | ||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> | ||
<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|x64'"> | ||
<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> | ||
</PropertyGroup> | ||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> | ||
<LinkIncremental>true</LinkIncremental> | ||
</PropertyGroup> | ||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | ||
<LinkIncremental>false</LinkIncremental> | ||
</PropertyGroup> | ||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> | ||
<LinkIncremental>false</LinkIncremental> | ||
</PropertyGroup> | ||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | ||
<ClCompile> | ||
<PrecompiledHeader>NotUsing</PrecompiledHeader> | ||
<WarningLevel>Level3</WarningLevel> | ||
<Optimization>Disabled</Optimization> | ||
<SDLCheck>true</SDLCheck> | ||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||
<ConformanceMode>true</ConformanceMode> | ||
</ClCompile> | ||
<Link> | ||
<SubSystem>Console</SubSystem> | ||
<GenerateDebugInformation>true</GenerateDebugInformation> | ||
</Link> | ||
</ItemDefinitionGroup> | ||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> | ||
<ClCompile> | ||
<PrecompiledHeader>NotUsing</PrecompiledHeader> | ||
<WarningLevel>Level3</WarningLevel> | ||
<Optimization>Disabled</Optimization> | ||
<SDLCheck>true</SDLCheck> | ||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||
<ConformanceMode>true</ConformanceMode> | ||
</ClCompile> | ||
<Link> | ||
<SubSystem>Console</SubSystem> | ||
<GenerateDebugInformation>true</GenerateDebugInformation> | ||
</Link> | ||
</ItemDefinitionGroup> | ||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | ||
<ClCompile> | ||
<PrecompiledHeader>NotUsing</PrecompiledHeader> | ||
<WarningLevel>Level3</WarningLevel> | ||
<Optimization>MaxSpeed</Optimization> | ||
<FunctionLevelLinking>true</FunctionLevelLinking> | ||
<IntrinsicFunctions>true</IntrinsicFunctions> | ||
<SDLCheck>true</SDLCheck> | ||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||
<ConformanceMode>true</ConformanceMode> | ||
</ClCompile> | ||
<Link> | ||
<SubSystem>Console</SubSystem> | ||
<EnableCOMDATFolding>true</EnableCOMDATFolding> | ||
<OptimizeReferences>true</OptimizeReferences> | ||
<GenerateDebugInformation>true</GenerateDebugInformation> | ||
</Link> | ||
</ItemDefinitionGroup> | ||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> | ||
<ClCompile> | ||
<PrecompiledHeader>NotUsing</PrecompiledHeader> | ||
<WarningLevel>Level3</WarningLevel> | ||
<Optimization>MaxSpeed</Optimization> | ||
<FunctionLevelLinking>true</FunctionLevelLinking> | ||
<IntrinsicFunctions>true</IntrinsicFunctions> | ||
<SDLCheck>true</SDLCheck> | ||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||
<ConformanceMode>true</ConformanceMode> | ||
</ClCompile> | ||
<Link> | ||
<SubSystem>Console</SubSystem> | ||
<EnableCOMDATFolding>true</EnableCOMDATFolding> | ||
<OptimizeReferences>true</OptimizeReferences> | ||
<GenerateDebugInformation>true</GenerateDebugInformation> | ||
</Link> | ||
</ItemDefinitionGroup> | ||
<ItemGroup> | ||
<ClInclude Include="stdafx.h" /> | ||
<ClInclude Include="targetver.h" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<ClCompile Include="..\..\source\interactivity.cpp" /> | ||
<ClCompile Include="InteractiveScreenControlSample.cpp" /> | ||
<ClCompile Include="stdafx.cpp"> | ||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> | ||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader> | ||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader> | ||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader> | ||
</ClCompile> | ||
</ItemGroup> | ||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> | ||
<ImportGroup Label="ExtensionTargets"> | ||
</ImportGroup> | ||
</Project> |
36 changes: 36 additions & 0 deletions
36
samples/InteractiveScreenControlSample/InteractiveSample.vcxproj.filters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
<ItemGroup> | ||
<Filter Include="Source Files"> | ||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> | ||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> | ||
</Filter> | ||
<Filter Include="Header Files"> | ||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> | ||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> | ||
</Filter> | ||
<Filter Include="Resource Files"> | ||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> | ||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> | ||
</Filter> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<ClInclude Include="stdafx.h"> | ||
<Filter>Header Files</Filter> | ||
</ClInclude> | ||
<ClInclude Include="targetver.h"> | ||
<Filter>Header Files</Filter> | ||
</ClInclude> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<ClCompile Include="stdafx.cpp"> | ||
<Filter>Source Files</Filter> | ||
</ClCompile> | ||
<ClCompile Include="..\..\source\interactivity.cpp"> | ||
<Filter>Source Files</Filter> | ||
</ClCompile> | ||
<ClCompile Include="InteractiveScreenControlSample.cpp"> | ||
<Filter>Source Files</Filter> | ||
</ClCompile> | ||
</ItemGroup> | ||
</Project> |
168 changes: 168 additions & 0 deletions
168
samples/InteractiveScreenControlSample/InteractiveScreenControlSample.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
#include "stdafx.h" | ||
#include "../../source/interactivity.h" | ||
#include "../../source/internal/rapidjson/Document.h" | ||
|
||
#include <windows.h> | ||
#include <shellapi.h> | ||
|
||
// STL includes | ||
#include <chrono> | ||
#include <thread> | ||
#include <iostream> | ||
#include <map> | ||
#include <string> | ||
|
||
#define CLIENT_ID "f0d20e2d263b75894f5cdaabc8a344b99b1ea6f9ecb7fa4f" | ||
#define INTERACTIVE_ID "247834" | ||
#define SHARE_CODE "v8t3hlaa" | ||
|
||
#define MIXER_DEBUG 0 | ||
|
||
std::map<std::string, std::string> controlsByTransaction; | ||
|
||
// Display an OAuth consent page to the user. | ||
int authorize(std::string& authorization); | ||
|
||
// Handle interactive input. | ||
void handle_interactive_input(void* context, interactive_session session, const interactive_input* input); | ||
|
||
int main() | ||
{ | ||
int err = 0; | ||
|
||
#if MIXER_DEBUG | ||
interactive_config_debug(interactive_debug_trace, [](const interactive_debug_level dbgMsgType, const char* dbgMsg, size_t dbgMsgSize) | ||
{ | ||
std::cout << dbgMsg << std::endl; | ||
}); | ||
#endif | ||
|
||
// Get an authorization token for the user to pass to the connect function. | ||
std::string authorization; | ||
err = authorize(authorization); | ||
if (err) return err; | ||
|
||
// Connect to the user's interactive channel, using the interactive project specified by the version ID. | ||
interactive_session session; | ||
err = interactive_open_session(authorization.c_str(), INTERACTIVE_ID, SHARE_CODE, false, &session); | ||
if (err) return err; | ||
|
||
// Register a callback for button presses. | ||
err = interactive_set_input_handler(session, handle_interactive_input); | ||
if (err) return err; | ||
|
||
// Now notify participants that interactive is ready. | ||
err = interactive_set_ready(session, true); | ||
if (err) return err; | ||
|
||
// Simulate game update loop. All previously registered session callbacks will be called from this thread. | ||
for (;;) | ||
{ | ||
// This call processes any waiting messages from the interactive service. If there are no messages this returns immediately. | ||
err = interactive_run(session, 1); | ||
if (err) break; | ||
std::this_thread::sleep_for(std::chrono::milliseconds(16)); | ||
} | ||
|
||
interactive_close_session(session); | ||
|
||
return err; | ||
} | ||
|
||
int authorize(std::string& authorization) | ||
{ | ||
int err = 0; | ||
char shortCode[7]; | ||
size_t shortCodeLength = _countof(shortCode); | ||
char shortCodeHandle[1024]; | ||
size_t shortCodeHandleLength = _countof(shortCodeHandle); | ||
|
||
// Get an OAuth short code from the user. For more information about OAuth see: https://oauth.net/2/ | ||
err = interactive_auth_get_short_code(CLIENT_ID, nullptr, shortCode, &shortCodeLength, shortCodeHandle, &shortCodeHandleLength); | ||
if (err) return err; | ||
|
||
// Pop the browser for the user to approve access. | ||
std::string authUrl = std::string("https://www.mixer.com/go?code=") + shortCode; | ||
ShellExecuteA(0, 0, authUrl.c_str(), nullptr, nullptr, SW_SHOW); | ||
|
||
// Wait for OAuth token response. | ||
char refreshTokenBuffer[1024]; | ||
size_t refreshTokenLength = _countof(refreshTokenBuffer); | ||
err = interactive_auth_wait_short_code(CLIENT_ID, nullptr, shortCodeHandle, refreshTokenBuffer, &refreshTokenLength); | ||
if (err) | ||
{ | ||
if (MIXER_ERROR_TIMED_OUT == err) | ||
{ | ||
std::cout << "Authorization timed out, user did not approve access within the time limit." << std::endl; | ||
} | ||
else if (MIXER_ERROR_AUTH_DENIED == err) | ||
{ | ||
std::cout << "User denied access." << std::endl; | ||
} | ||
|
||
return err; | ||
} | ||
|
||
/* | ||
* TODO: This is where you would serialize the refresh token locally or on your own service for future use in a way that is associated with the current user. | ||
* Future calls would then only need to check if the token is stale, refresh it if so, and then parse the new authorization header. | ||
*/ | ||
|
||
// Extract the authorization header from the refresh token. | ||
char authBuffer[1024]; | ||
size_t authBufferLength = _countof(authBuffer); | ||
err = interactive_auth_parse_refresh_token(refreshTokenBuffer, authBuffer, &authBufferLength); | ||
if (err) return err; | ||
|
||
// Set the authorization out parameter. | ||
authorization = std::string(authBuffer, authBufferLength); | ||
return 0; | ||
} | ||
|
||
int get_participant_name(interactive_session session, const char* participantId, std::string& participantName) | ||
{ | ||
// Get the participant's name. | ||
size_t participantNameLength = 0; | ||
|
||
// First call with a nullptr to get the required size for the user's name, MIXER_ERROR_BUFFER_SIZE is the expected return value. | ||
int err = interactive_participant_get_user_name(session, participantId, nullptr, &participantNameLength); | ||
if (MIXER_ERROR_BUFFER_SIZE != err) | ||
{ | ||
return err; | ||
} | ||
|
||
// Resize the string to the correct size and call it again. | ||
participantName.resize(participantNameLength); | ||
err = interactive_participant_get_user_name(session, participantId, (char*)participantName.data(), &participantNameLength); | ||
// STL strings don't need a trailing null character. | ||
participantName = participantName.erase(participantNameLength - 1); | ||
|
||
return 0; | ||
} | ||
|
||
void handle_interactive_input(void* context, interactive_session session, const interactive_input* input) | ||
{ | ||
// Get the participant's Mixer name to give them attribution. | ||
std::string participantName; | ||
int err = get_participant_name(session, input->participantId, participantName); | ||
if (err) | ||
{ | ||
std::cerr << "Failed to get participant user name (" << std::to_string(err) << ")" << std::endl; | ||
return; | ||
} | ||
|
||
// Now handle the input based on input type. | ||
if ((input_type_key == input->type || input_type_click == input->type) && interactive_button_action_down == input->buttonData.action) | ||
{ | ||
float x = input->coordinateData.x; | ||
float y = input->coordinateData.y; | ||
std::cout << participantName << " clicked x: " + std::to_string(x) << " y: " << std::to_string(y) << std::endl; | ||
} | ||
else if (input_type_move == input->type) | ||
{ | ||
// Show which user moved the joystick. | ||
float x = input->coordinateData.x; | ||
float y = input->coordinateData.y; | ||
std::cout << participantName << " moved pointer to x: " + std::to_string(x) << " y: " << std::to_string(y) << std::endl; | ||
} | ||
} |
Oops, something went wrong.