├── .gitignore
├── CONTRIBUTING.md
├── Config
└── FilterPlugin.ini
├── Content
├── Blueprints
│ ├── ExampleActor.uasset
│ ├── ExampleUI.uasset
│ └── Interface
│ │ ├── StomtUILayerEnum.uasset
│ │ └── StomtWidgetBP.uasset
├── Maps
│ └── StomtExampleMap.umap
├── Materials
│ └── IconMaskMaterial.uasset
├── Sprites
│ ├── Circle-black.png
│ ├── Circle-black.uasset
│ ├── Circle-black64x64.png
│ ├── Circle-black64x64.uasset
│ ├── Circle.png
│ ├── Circle.uasset
│ ├── LoginButton.png
│ ├── LoginButton.uasset
│ ├── LoginButtonClean.png
│ ├── LoginButtonClean.uasset
│ ├── Stomt_Logo+Wordmark_Master_RGB.png
│ ├── Stomt_Logo+Wordmark_Master_RGB.uasset
│ ├── WidgetForm.png
│ ├── WidgetForm.uasset
│ ├── WidgetFormHighRes.png
│ ├── WidgetFormHighRes.uasset
│ ├── WidgetFormHighRes15.png
│ ├── WidgetFormHighRes15.uasset
│ ├── WidgetFormHighRes30_.uasset
│ ├── WidgetFormHighRes30pc.png
│ ├── back-arrow-circular-symbol.png
│ ├── back-arrow-circular-symbol.uasset
│ ├── call-arrow-short.png
│ ├── call-arrow-short.uasset
│ ├── circle-32.png
│ ├── circle-32.uasset
│ ├── form_background.png
│ ├── form_background.uasset
│ ├── icon_back_gray.png
│ ├── icon_back_gray.uasset
│ ├── icon_image_gray.png
│ ├── icon_image_gray.uasset
│ ├── icon_plus-gray.png
│ ├── icon_plus-gray.uasset
│ ├── icon_refresh_gray.png
│ ├── icon_refresh_gray.uasset
│ ├── icon_refresh_white.png
│ ├── icon_refresh_white.uasset
│ ├── like.png
│ ├── like.uasset
│ ├── loading.png
│ ├── loading.uasset
│ ├── maxresdefault.jpg
│ ├── maxresdefault.uasset
│ ├── plus_disabled.png
│ ├── plus_disabled.uasset
│ ├── plus_enabled.png
│ ├── plus_enabled.uasset
│ ├── rect.png
│ ├── rect.uasset
│ ├── sprite150++128.png
│ ├── sprite150++128.uasset
│ ├── sprite150++256.png
│ ├── sprite150++256.uasset
│ ├── sprite150++64-greyborder.png
│ ├── sprite150++64-greyborder.uasset
│ ├── sprite150++64.png
│ ├── sprite150++64.uasset
│ ├── sprite150-border.PNG
│ ├── sprite150-border.uasset
│ ├── sprite150-border1024.PNG
│ ├── sprite150-border1024.uasset
│ ├── sprite150.PNG
│ ├── sprite150.uasset
│ ├── spriteCircle.PNG
│ ├── spriteCircle.uasset
│ ├── spriteMagicWhite.uasset
│ ├── stomt-icon.png
│ ├── stomt-icon.uasset
│ ├── submit_enabled.png
│ ├── submit_enabled.uasset
│ ├── target_icon_mask.png
│ ├── target_icon_mask.uasset
│ ├── wish-border.png
│ └── wish-border.uasset
└── ThirdParty
│ └── Fonts
│ ├── IndieFlower.uasset
│ ├── IndieFlower_Font.uasset
│ ├── Lato-Bold.uasset
│ ├── Lato-Bold_Font.uasset
│ ├── Lato-Light.uasset
│ ├── Lato-Light_Font.uasset
│ ├── Lato-Regular.uasset
│ └── Lato-Regular_Font.uasset
├── DEVELOPMENT.md
├── Docs
├── Images
│ ├── unreal_StomtPlugin_configure_AppID.png
│ ├── unreal_StomtPlugin_enable_engine_content.png
│ ├── unreal_StomtPlugin_find_widget_content.png
│ └── unreal_enable_StomtPlugin.png
└── OpenFontLicense.txt
├── LICENSE.md
├── README.md
├── Resources
├── Icon128.png
└── languages.json
├── Source
└── StomtPlugin
│ ├── Private
│ ├── Stomt.cpp
│ ├── StomtAPI.cpp
│ ├── StomtConfig.cpp
│ ├── StomtJsonObject.cpp
│ ├── StomtJsonValue.cpp
│ ├── StomtLabel.cpp
│ ├── StomtPlugin.cpp
│ ├── StomtPluginWidget.cpp
│ ├── StomtRestRequest.cpp
│ └── StomtTrack.cpp
│ ├── Public
│ ├── Stomt.h
│ ├── StomtAPI.h
│ ├── StomtConfig.h
│ ├── StomtJsonObject.h
│ ├── StomtJsonValue.h
│ ├── StomtLabel.h
│ ├── StomtPlugin.h
│ ├── StomtPluginPrivatePCH.h
│ ├── StomtPluginWidget.h
│ ├── StomtRestRequest.h
│ └── StomtTrack.h
│ └── StomtPlugin.Build.cs
├── StomtPlugin.uplugin
├── pack.sh
└── scripts
├── delete_branches.sh
├── push_branches.sh
└── update_branches.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | #################
2 | ## Eclipse
3 | #################
4 |
5 | *.pydevproject
6 | .project
7 | .metadata
8 | bin/
9 | tmp/
10 | *.tmp
11 | *.bak
12 | *.swp
13 | *~.nib
14 | local.properties
15 | .classpath
16 | .settings/
17 | .loadpath
18 |
19 | # External tool builders
20 | .externalToolBuilders/
21 |
22 | # Locally stored "Eclipse launch configurations"
23 | *.launch
24 |
25 | # CDT-specific
26 | .cproject
27 |
28 | # PDT-specific
29 | .buildpath
30 |
31 |
32 | #################
33 | ## Visual Studio
34 | #################
35 |
36 | ## Ignore Visual Studio temporary files, build results, and
37 | ## files generated by popular Visual Studio add-ons.
38 |
39 | # User-specific files
40 | *.suo
41 | *.user
42 | *.sln.docstates
43 | *.sln
44 | *.sdf
45 |
46 | # Build results
47 |
48 | [Dd]ebug/
49 | [Rr]elease/
50 | x64/
51 | build/
52 | [Bb]in/
53 | [Oo]bj/
54 |
55 | # MSTest test Results
56 | [Tt]est[Rr]esult*/
57 | [Bb]uild[Ll]og.*
58 |
59 | *_i.c
60 | *_p.c
61 | *.ilk
62 | *.meta
63 | *.obj
64 | *.pch
65 | *.pdb
66 | *.pgc
67 | *.pgd
68 | *.rsp
69 | *.sbr
70 | *.tlb
71 | *.tli
72 | *.tlh
73 | *.tmp
74 | *.tmp_proj
75 | *.log
76 | *.vspscc
77 | *.vssscc
78 | .builds
79 | *.pidb
80 | *.log
81 | *.scc
82 |
83 | # Visual C++ cache files
84 | ipch/
85 | *.aps
86 | *.ncb
87 | *.opensdf
88 | *.sdf
89 | *.cachefile
90 |
91 | # Visual Studio profiler
92 | *.psess
93 | *.vsp
94 | *.vspx
95 |
96 | # Guidance Automation Toolkit
97 | *.gpState
98 |
99 | # ReSharper is a .NET coding add-in
100 | _ReSharper*/
101 | *.[Rr]e[Ss]harper
102 |
103 | # TeamCity is a build add-in
104 | _TeamCity*
105 |
106 | # DotCover is a Code Coverage Tool
107 | *.dotCover
108 |
109 | # NCrunch
110 | *.ncrunch*
111 | .*crunch*.local.xml
112 |
113 | # Installshield output folder
114 | [Ee]xpress/
115 |
116 | # DocProject is a documentation generator add-in
117 | DocProject/buildhelp/
118 | DocProject/Help/*.HxT
119 | DocProject/Help/*.HxC
120 | DocProject/Help/*.hhc
121 | DocProject/Help/*.hhk
122 | DocProject/Help/*.hhp
123 | DocProject/Help/Html2
124 | DocProject/Help/html
125 |
126 | # Click-Once directory
127 | publish/
128 |
129 | # Publish Web Output
130 | *.Publish.xml
131 | *.pubxml
132 |
133 | # NuGet Packages Directory
134 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line
135 | #packages/
136 |
137 | # Windows Azure Build Output
138 | csx
139 | *.build.csdef
140 |
141 | # Windows Store app package directory
142 | AppPackages/
143 |
144 | # Others
145 | sql/
146 | *.Cache
147 | ClientBin/
148 | [Ss]tyle[Cc]op.*
149 | ~$*
150 | *~
151 | *.dbmdl
152 | *.[Pp]ublish.xml
153 | *.pfx
154 | *.publishsettings
155 |
156 | # RIA/Silverlight projects
157 | Generated_Code/
158 |
159 | # Backup & report files from converting an old project file to a newer
160 | # Visual Studio version. Backup files are not needed, because we have git ;-)
161 | _UpgradeReport_Files/
162 | Backup*/
163 | UpgradeLog*.XML
164 | UpgradeLog*.htm
165 |
166 | # SQL Server files
167 | App_Data/*.mdf
168 | App_Data/*.ldf
169 |
170 | #############
171 | ## Windows detritus
172 | #############
173 |
174 | # Windows image file caches
175 | Thumbs.db
176 | ehthumbs.db
177 |
178 | # Folder config file
179 | Desktop.ini
180 |
181 | # Recycle Bin used on file shares
182 | $RECYCLE.BIN/
183 |
184 | # Mac crap
185 | .DS_Store
186 |
187 |
188 | #############
189 | ## Python
190 | #############
191 |
192 | *.py[co]
193 |
194 | # Packages
195 | *.egg
196 | *.egg-info
197 | dist/
198 | build/
199 | eggs/
200 | parts/
201 | var/
202 | sdist/
203 | develop-eggs/
204 | .installed.cfg
205 |
206 | # Installer logs
207 | pip-log.txt
208 |
209 | # Unit test / coverage reports
210 | .coverage
211 | .tox
212 |
213 | #Translations
214 | *.mo
215 |
216 | #Mr Developer
217 | .mr.developer.cfg
218 |
219 | # Compiled Object files
220 | *.slo
221 | *.lo
222 | *.o
223 | *.obj
224 |
225 | # Compiled Dynamic libraries
226 | *.so
227 | *.dylib
228 | *.dll
229 |
230 | # Compiled Static libraries
231 | *.lai
232 | *.la
233 | *.a
234 | *.lib
235 |
236 | # Executables
237 | *.exe
238 | *.out
239 | *.app
240 |
241 | #Unreal Engine
242 |
243 | Binaries/
244 | DerivedDataCache/
245 | Intermediate/
246 | Saved/
247 | *.sln
248 | stomt.VC.opendb
249 | .vs
250 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | When contributing to this repository, please first discuss the change you wish to make via issue,
4 | email, or any other method with the owners of this repository before making a change.
5 |
6 | Please note we have a code of conduct, please follow it in all your interactions with the project.
7 |
8 | ## Pull Request Process
9 |
10 | 1. Ensure any install or build dependencies are removed before the end of the layer when doing a
11 | build.
12 | 2. Update the README.md with details of changes to the interface, this includes new environment
13 | variables, exposed ports, useful file locations and container parameters.
14 | 3. Increase the version numbers in any examples files and the README.md to the new version that this
15 | Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/).
16 | 4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you
17 | do not have permission to do that, you may request the second reviewer to merge it for you.
18 |
19 | ## Code of Conduct
20 |
21 | ### Our Pledge
22 |
23 | In the interest of fostering an open and welcoming environment, we as
24 | contributors and maintainers pledge to making participation in our project and
25 | our community a harassment-free experience for everyone, regardless of age, body
26 | size, disability, ethnicity, gender identity and expression, level of experience,
27 | nationality, personal appearance, race, religion, or sexual identity and
28 | orientation.
29 |
30 | ### Our Standards
31 |
32 | Examples of behavior that contributes to creating a positive environment
33 | include:
34 |
35 | * Using welcoming and inclusive language
36 | * Being respectful of differing viewpoints and experiences
37 | * Gracefully accepting constructive criticism
38 | * Focusing on what is best for the community
39 | * Showing empathy towards other community members
40 |
41 | Examples of unacceptable behavior by participants include:
42 |
43 | * The use of sexualized language or imagery and unwelcome sexual attention or
44 | advances
45 | * Trolling, insulting/derogatory comments, and personal or political attacks
46 | * Public or private harassment
47 | * Publishing others' private information, such as a physical or electronic
48 | address, without explicit permission
49 | * Other conduct which could reasonably be considered inappropriate in a
50 | professional setting
51 |
52 | ### Our Responsibilities
53 |
54 | Project maintainers are responsible for clarifying the standards of acceptable
55 | behavior and are expected to take appropriate and fair corrective action in
56 | response to any instances of unacceptable behavior.
57 |
58 | Project maintainers have the right and responsibility to remove, edit, or
59 | reject comments, commits, code, wiki edits, issues, and other contributions
60 | that are not aligned to this Code of Conduct, or to ban temporarily or
61 | permanently any contributor for other behaviors that they deem inappropriate,
62 | threatening, offensive, or harmful.
63 |
64 | ### Scope
65 |
66 | This Code of Conduct applies both within project spaces and in public spaces
67 | when an individual is representing the project or its community. Examples of
68 | representing a project or community include using an official project e-mail
69 | address, posting via an official social media account, or acting as an appointed
70 | representative at an online or offline event. Representation of a project may be
71 | further defined and clarified by project maintainers.
72 |
73 | ### Enforcement
74 |
75 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
76 | reported by contacting the project team at [devs@stomt.com]. All
77 | complaints will be reviewed and investigated and will result in a response that
78 | is deemed necessary and appropriate to the circumstances. The project team is
79 | obligated to maintain confidentiality with regard to the reporter of an incident.
80 | Further details of specific enforcement policies may be posted separately.
81 |
82 | Project maintainers who do not follow or enforce the Code of Conduct in good
83 | faith may face temporary or permanent repercussions as determined by other
84 | members of the project's leadership.
85 |
86 | ### Attribution
87 |
88 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
89 | available at [http://contributor-covenant.org/version/1/4][version]
90 |
91 | [homepage]: http://contributor-covenant.org
92 | [version]: http://contributor-covenant.org/version/1/4/
93 |
--------------------------------------------------------------------------------
/Config/FilterPlugin.ini:
--------------------------------------------------------------------------------
1 | [FilterPlugin]
2 | /Docs/...
3 |
--------------------------------------------------------------------------------
/Content/Blueprints/ExampleActor.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Blueprints/ExampleActor.uasset
--------------------------------------------------------------------------------
/Content/Blueprints/ExampleUI.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Blueprints/ExampleUI.uasset
--------------------------------------------------------------------------------
/Content/Blueprints/Interface/StomtUILayerEnum.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Blueprints/Interface/StomtUILayerEnum.uasset
--------------------------------------------------------------------------------
/Content/Blueprints/Interface/StomtWidgetBP.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Blueprints/Interface/StomtWidgetBP.uasset
--------------------------------------------------------------------------------
/Content/Maps/StomtExampleMap.umap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Maps/StomtExampleMap.umap
--------------------------------------------------------------------------------
/Content/Materials/IconMaskMaterial.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Materials/IconMaskMaterial.uasset
--------------------------------------------------------------------------------
/Content/Sprites/Circle-black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/Circle-black.png
--------------------------------------------------------------------------------
/Content/Sprites/Circle-black.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/Circle-black.uasset
--------------------------------------------------------------------------------
/Content/Sprites/Circle-black64x64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/Circle-black64x64.png
--------------------------------------------------------------------------------
/Content/Sprites/Circle-black64x64.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/Circle-black64x64.uasset
--------------------------------------------------------------------------------
/Content/Sprites/Circle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/Circle.png
--------------------------------------------------------------------------------
/Content/Sprites/Circle.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/Circle.uasset
--------------------------------------------------------------------------------
/Content/Sprites/LoginButton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/LoginButton.png
--------------------------------------------------------------------------------
/Content/Sprites/LoginButton.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/LoginButton.uasset
--------------------------------------------------------------------------------
/Content/Sprites/LoginButtonClean.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/LoginButtonClean.png
--------------------------------------------------------------------------------
/Content/Sprites/LoginButtonClean.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/LoginButtonClean.uasset
--------------------------------------------------------------------------------
/Content/Sprites/Stomt_Logo+Wordmark_Master_RGB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/Stomt_Logo+Wordmark_Master_RGB.png
--------------------------------------------------------------------------------
/Content/Sprites/Stomt_Logo+Wordmark_Master_RGB.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/Stomt_Logo+Wordmark_Master_RGB.uasset
--------------------------------------------------------------------------------
/Content/Sprites/WidgetForm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/WidgetForm.png
--------------------------------------------------------------------------------
/Content/Sprites/WidgetForm.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/WidgetForm.uasset
--------------------------------------------------------------------------------
/Content/Sprites/WidgetFormHighRes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/WidgetFormHighRes.png
--------------------------------------------------------------------------------
/Content/Sprites/WidgetFormHighRes.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/WidgetFormHighRes.uasset
--------------------------------------------------------------------------------
/Content/Sprites/WidgetFormHighRes15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/WidgetFormHighRes15.png
--------------------------------------------------------------------------------
/Content/Sprites/WidgetFormHighRes15.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/WidgetFormHighRes15.uasset
--------------------------------------------------------------------------------
/Content/Sprites/WidgetFormHighRes30_.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/WidgetFormHighRes30_.uasset
--------------------------------------------------------------------------------
/Content/Sprites/WidgetFormHighRes30pc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/WidgetFormHighRes30pc.png
--------------------------------------------------------------------------------
/Content/Sprites/back-arrow-circular-symbol.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/back-arrow-circular-symbol.png
--------------------------------------------------------------------------------
/Content/Sprites/back-arrow-circular-symbol.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/back-arrow-circular-symbol.uasset
--------------------------------------------------------------------------------
/Content/Sprites/call-arrow-short.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/call-arrow-short.png
--------------------------------------------------------------------------------
/Content/Sprites/call-arrow-short.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/call-arrow-short.uasset
--------------------------------------------------------------------------------
/Content/Sprites/circle-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/circle-32.png
--------------------------------------------------------------------------------
/Content/Sprites/circle-32.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/circle-32.uasset
--------------------------------------------------------------------------------
/Content/Sprites/form_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/form_background.png
--------------------------------------------------------------------------------
/Content/Sprites/form_background.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/form_background.uasset
--------------------------------------------------------------------------------
/Content/Sprites/icon_back_gray.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/icon_back_gray.png
--------------------------------------------------------------------------------
/Content/Sprites/icon_back_gray.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/icon_back_gray.uasset
--------------------------------------------------------------------------------
/Content/Sprites/icon_image_gray.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/icon_image_gray.png
--------------------------------------------------------------------------------
/Content/Sprites/icon_image_gray.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/icon_image_gray.uasset
--------------------------------------------------------------------------------
/Content/Sprites/icon_plus-gray.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/icon_plus-gray.png
--------------------------------------------------------------------------------
/Content/Sprites/icon_plus-gray.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/icon_plus-gray.uasset
--------------------------------------------------------------------------------
/Content/Sprites/icon_refresh_gray.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/icon_refresh_gray.png
--------------------------------------------------------------------------------
/Content/Sprites/icon_refresh_gray.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/icon_refresh_gray.uasset
--------------------------------------------------------------------------------
/Content/Sprites/icon_refresh_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/icon_refresh_white.png
--------------------------------------------------------------------------------
/Content/Sprites/icon_refresh_white.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/icon_refresh_white.uasset
--------------------------------------------------------------------------------
/Content/Sprites/like.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/like.png
--------------------------------------------------------------------------------
/Content/Sprites/like.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/like.uasset
--------------------------------------------------------------------------------
/Content/Sprites/loading.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/loading.png
--------------------------------------------------------------------------------
/Content/Sprites/loading.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/loading.uasset
--------------------------------------------------------------------------------
/Content/Sprites/maxresdefault.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/maxresdefault.jpg
--------------------------------------------------------------------------------
/Content/Sprites/maxresdefault.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/maxresdefault.uasset
--------------------------------------------------------------------------------
/Content/Sprites/plus_disabled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/plus_disabled.png
--------------------------------------------------------------------------------
/Content/Sprites/plus_disabled.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/plus_disabled.uasset
--------------------------------------------------------------------------------
/Content/Sprites/plus_enabled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/plus_enabled.png
--------------------------------------------------------------------------------
/Content/Sprites/plus_enabled.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/plus_enabled.uasset
--------------------------------------------------------------------------------
/Content/Sprites/rect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/rect.png
--------------------------------------------------------------------------------
/Content/Sprites/rect.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/rect.uasset
--------------------------------------------------------------------------------
/Content/Sprites/sprite150++128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/sprite150++128.png
--------------------------------------------------------------------------------
/Content/Sprites/sprite150++128.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/sprite150++128.uasset
--------------------------------------------------------------------------------
/Content/Sprites/sprite150++256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/sprite150++256.png
--------------------------------------------------------------------------------
/Content/Sprites/sprite150++256.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/sprite150++256.uasset
--------------------------------------------------------------------------------
/Content/Sprites/sprite150++64-greyborder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/sprite150++64-greyborder.png
--------------------------------------------------------------------------------
/Content/Sprites/sprite150++64-greyborder.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/sprite150++64-greyborder.uasset
--------------------------------------------------------------------------------
/Content/Sprites/sprite150++64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/sprite150++64.png
--------------------------------------------------------------------------------
/Content/Sprites/sprite150++64.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/sprite150++64.uasset
--------------------------------------------------------------------------------
/Content/Sprites/sprite150-border.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/sprite150-border.PNG
--------------------------------------------------------------------------------
/Content/Sprites/sprite150-border.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/sprite150-border.uasset
--------------------------------------------------------------------------------
/Content/Sprites/sprite150-border1024.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/sprite150-border1024.PNG
--------------------------------------------------------------------------------
/Content/Sprites/sprite150-border1024.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/sprite150-border1024.uasset
--------------------------------------------------------------------------------
/Content/Sprites/sprite150.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/sprite150.PNG
--------------------------------------------------------------------------------
/Content/Sprites/sprite150.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/sprite150.uasset
--------------------------------------------------------------------------------
/Content/Sprites/spriteCircle.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/spriteCircle.PNG
--------------------------------------------------------------------------------
/Content/Sprites/spriteCircle.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/spriteCircle.uasset
--------------------------------------------------------------------------------
/Content/Sprites/spriteMagicWhite.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/spriteMagicWhite.uasset
--------------------------------------------------------------------------------
/Content/Sprites/stomt-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/stomt-icon.png
--------------------------------------------------------------------------------
/Content/Sprites/stomt-icon.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/stomt-icon.uasset
--------------------------------------------------------------------------------
/Content/Sprites/submit_enabled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/submit_enabled.png
--------------------------------------------------------------------------------
/Content/Sprites/submit_enabled.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/submit_enabled.uasset
--------------------------------------------------------------------------------
/Content/Sprites/target_icon_mask.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/target_icon_mask.png
--------------------------------------------------------------------------------
/Content/Sprites/target_icon_mask.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/target_icon_mask.uasset
--------------------------------------------------------------------------------
/Content/Sprites/wish-border.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/wish-border.png
--------------------------------------------------------------------------------
/Content/Sprites/wish-border.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/Sprites/wish-border.uasset
--------------------------------------------------------------------------------
/Content/ThirdParty/Fonts/IndieFlower.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/ThirdParty/Fonts/IndieFlower.uasset
--------------------------------------------------------------------------------
/Content/ThirdParty/Fonts/IndieFlower_Font.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/ThirdParty/Fonts/IndieFlower_Font.uasset
--------------------------------------------------------------------------------
/Content/ThirdParty/Fonts/Lato-Bold.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/ThirdParty/Fonts/Lato-Bold.uasset
--------------------------------------------------------------------------------
/Content/ThirdParty/Fonts/Lato-Bold_Font.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/ThirdParty/Fonts/Lato-Bold_Font.uasset
--------------------------------------------------------------------------------
/Content/ThirdParty/Fonts/Lato-Light.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/ThirdParty/Fonts/Lato-Light.uasset
--------------------------------------------------------------------------------
/Content/ThirdParty/Fonts/Lato-Light_Font.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/ThirdParty/Fonts/Lato-Light_Font.uasset
--------------------------------------------------------------------------------
/Content/ThirdParty/Fonts/Lato-Regular.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/ThirdParty/Fonts/Lato-Regular.uasset
--------------------------------------------------------------------------------
/Content/ThirdParty/Fonts/Lato-Regular_Font.uasset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Content/ThirdParty/Fonts/Lato-Regular_Font.uasset
--------------------------------------------------------------------------------
/DEVELOPMENT.md:
--------------------------------------------------------------------------------
1 | # Development
2 |
3 | ## Branches
4 |
5 | This repository contains a branch for each Engine Version. Only perform changes in one of these branches if the changes are specific for this version. All other changes are made in the `master` - this branch uses our base version `UE/4.20`.
6 |
7 | - UE/4.16 [deprecated]
8 | - UE/4.17 [deprecated]
9 | - UE/4.18 [deprecated]
10 | - UE/4.19 [deprecated]
11 | - UE/4.20 = master
12 | - UE/4.21 = master + changed EngineVersion
13 | - UE/4.22 = master + changed EngineVersion
14 | - UE/4.23 = master + changed EngineVersion
15 | - UE/4.24 = master + changed EngineVersion
16 | - UE/4.25 = master + changed EngineVersion
17 | - UE/4.26 = master + changed EngineVersion
18 |
19 | ## Release
20 |
21 | The following scripts help to perform a release.
22 |
23 | 1. Ensure that all nessessary changes have been made in the `master` branch.
24 |
25 | * Increase Version in StomtPlugin.uplugin
26 | * Update version number in StomtPlugin.uplugin
27 | * Update version number in StomtTrack.cpp line 36
28 | * commit changes "git commit -am 'bump version to X.X.X"
29 | * create tag "git tag -a vX.X.X"
30 |
31 | 2. Use `sh scripts/delete_branches.sh` to remove local changes in other branches.
32 |
33 | 3. Update the version branches by running `sh scripts/update_branches.sh`. Confirm the merges and merge commits.
34 |
35 | 4. Push the updated branches to GitHub by running `sh scripts/push_branches.sh`.
36 |
37 | 5. Now pack the version archives `sh pack.sh` and upload them for the store.
38 |
--------------------------------------------------------------------------------
/Docs/Images/unreal_StomtPlugin_configure_AppID.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Docs/Images/unreal_StomtPlugin_configure_AppID.png
--------------------------------------------------------------------------------
/Docs/Images/unreal_StomtPlugin_enable_engine_content.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Docs/Images/unreal_StomtPlugin_enable_engine_content.png
--------------------------------------------------------------------------------
/Docs/Images/unreal_StomtPlugin_find_widget_content.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Docs/Images/unreal_StomtPlugin_find_widget_content.png
--------------------------------------------------------------------------------
/Docs/Images/unreal_enable_StomtPlugin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Docs/Images/unreal_enable_StomtPlugin.png
--------------------------------------------------------------------------------
/Docs/OpenFontLicense.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2010-2014 by tyPoland Lukasz Dziedzic (team@latofonts.com) with Reserved Font Name "Lato"
2 |
3 | This Font Software is licensed under the SIL Open Font License, Version 1.1.
4 | This license is copied below, and is also available with a FAQ at:
5 | http://scripts.sil.org/OFL
6 |
7 | Copyright (c) 2010, Kimberly Geswein (kimberlygeswein.com)
8 |
9 | This Font Software is licensed under the SIL Open Font License, Version 1.1.
10 | This license is copied below, and is also available with a FAQ at:
11 | http://scripts.sil.org/OFL
12 |
13 | -----------------------------------------------------------
14 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
15 | -----------------------------------------------------------
16 |
17 | PREAMBLE
18 | The goals of the Open Font License (OFL) are to stimulate worldwide
19 | development of collaborative font projects, to support the font creation
20 | efforts of academic and linguistic communities, and to provide a free and
21 | open framework in which fonts may be shared and improved in partnership
22 | with others.
23 |
24 | The OFL allows the licensed fonts to be used, studied, modified and
25 | redistributed freely as long as they are not sold by themselves. The
26 | fonts, including any derivative works, can be bundled, embedded,
27 | redistributed and/or sold with any software provided that any reserved
28 | names are not used by derivative works. The fonts and derivatives,
29 | however, cannot be released under any other type of license. The
30 | requirement for fonts to remain under this license does not apply
31 | to any document created using the fonts or their derivatives.
32 |
33 | DEFINITIONS
34 | "Font Software" refers to the set of files released by the Copyright
35 | Holder(s) under this license and clearly marked as such. This may
36 | include source files, build scripts and documentation.
37 |
38 | "Reserved Font Name" refers to any names specified as such after the
39 | copyright statement(s).
40 |
41 | "Original Version" refers to the collection of Font Software components as
42 | distributed by the Copyright Holder(s).
43 |
44 | "Modified Version" refers to any derivative made by adding to, deleting,
45 | or substituting -- in part or in whole -- any of the components of the
46 | Original Version, by changing formats or by porting the Font Software to a
47 | new environment.
48 |
49 | "Author" refers to any designer, engineer, programmer, technical
50 | writer or other person who contributed to the Font Software.
51 |
52 | PERMISSION & CONDITIONS
53 | Permission is hereby granted, free of charge, to any person obtaining
54 | a copy of the Font Software, to use, study, copy, merge, embed, modify,
55 | redistribute, and sell modified and unmodified copies of the Font
56 | Software, subject to the following conditions:
57 |
58 | 1) Neither the Font Software nor any of its individual components,
59 | in Original or Modified Versions, may be sold by itself.
60 |
61 | 2) Original or Modified Versions of the Font Software may be bundled,
62 | redistributed and/or sold with any software, provided that each copy
63 | contains the above copyright notice and this license. These can be
64 | included either as stand-alone text files, human-readable headers or
65 | in the appropriate machine-readable metadata fields within text or
66 | binary files as long as those fields can be easily viewed by the user.
67 |
68 | 3) No Modified Version of the Font Software may use the Reserved Font
69 | Name(s) unless explicit written permission is granted by the corresponding
70 | Copyright Holder. This restriction only applies to the primary font name as
71 | presented to the users.
72 |
73 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
74 | Software shall not be used to promote, endorse or advertise any
75 | Modified Version, except to acknowledge the contribution(s) of the
76 | Copyright Holder(s) and the Author(s) or with their explicit written
77 | permission.
78 |
79 | 5) The Font Software, modified or unmodified, in part or in whole,
80 | must be distributed entirely under this license, and must not be
81 | distributed under any other license. The requirement for fonts to
82 | remain under this license does not apply to any document created
83 | using the Font Software.
84 |
85 | TERMINATION
86 | This license becomes null and void if any of the above conditions are
87 | not met.
88 |
89 | DISCLAIMER
90 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
91 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
92 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
93 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
94 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
95 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
96 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
97 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
98 | OTHER DEALINGS IN THE FONT SOFTWARE.
99 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2018 STOMT GmbH
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Collect Feedback In-Game | STOMT for Unreal Engine 4
2 |
3 | **Implementation Time: ~20 Minutes (incl. Triggers)**
4 |
5 | **Base Unreal Version: 4.20
6 | (For specific versions visit:
7 | [4.16](https://github.com/stomt/stomt-unreal-plugin/tree/UE/4.16),
8 | [4.17](https://github.com/stomt/stomt-unreal-plugin/tree/UE/4.17),
9 | [4.18](https://github.com/stomt/stomt-unreal-plugin/tree/UE/4.18),
10 | [4.19](https://github.com/stomt/stomt-unreal-plugin/tree/UE/4.19),
11 | [4.20](https://github.com/stomt/stomt-unreal-plugin/tree/UE/4.20),
12 | [4.21](https://github.com/stomt/stomt-unreal-plugin/tree/UE/4.21),
13 | [4.22](https://github.com/stomt/stomt-unreal-plugin/tree/UE/4.22),
14 | [4.23](https://github.com/stomt/stomt-unreal-plugin/tree/UE/4.23),
15 | [4.24](https://github.com/stomt/stomt-unreal-plugin/tree/UE/4.24),
16 | [4.25](https://github.com/stomt/stomt-unreal-plugin/tree/UE/4.25),
17 | [4.26](https://github.com/stomt/stomt-unreal-plugin/tree/UE/4.26)
18 | )**
19 |
20 |
21 |
22 |
23 |
24 | This SDK allows the easy integration of the feedback solution [www.stomt.com](https://www.stomt.com/) in your Unreal apps and games.
25 |
26 |
27 | ## Use-Cases
28 |
29 | Example Games that use our integrations:
30 |
31 | * [Empires of the Undergrowth](https://www.stomt.com/empires-of-the-undergrowth)
32 | * [All Walls Must Fall](https://www.stomt.com/AWMF)
33 | * [Pantropy](https://www.stomt.com/pantropy)
34 |
35 |
36 | ## Installation
37 |
38 | ### Installation via Marketplace (recommended)
39 |
40 | 1. [Download](com.epicgames.launcher://ue/marketplace/content/7980672d57664bb5a567ff39f5106af6) the Plugin via the [Unreal Engine Marketplace](https://www.unrealengine.com/marketplace/stomt-collect-feedback-community-building)
41 |
42 | 2. Enable StomtPlugin in your Plugins Window (in Unreal Editor: `Edit -> Plugins -> Installed -> Widgets -> StomtPlugin`)
43 |
44 |
45 |
46 | 3. Enable "Show Engine Content" and "Show Plugin Content" in your Content Browser
47 |
48 |
49 |
50 | 4. Find StomtPlugin Content
51 |
52 |
53 |
54 | 5. Place the `ExampleActor` in your scene.
55 |
56 | 6. Click play to run the game and show the feedback widget by pressing `E`.
57 |
58 | _You should now see the feedback form window in your game. Try to toggle "I wish"/"I like" and send a test stomt to "My Game" (The default test target). Then continue with [Configuration](#configuration)._
59 |
60 | ### Manual Installation
61 |
62 | _If you use an older Unreal Engine version please check out the [`UE/[version]` branch](https://github.com/stomt/stomt-unreal-plugin/branches)._
63 |
64 | 1. Clone or download this repository into your projects `Plugins` directory.
65 |
66 | 1.2. **If you do not use C++ code in project:** use the `Add New` button in the editor and add a blank C++ class to your project.
67 | [Guide](https://docs.unrealengine.com/latest/INT/Programming/QuickStart/2/index.html)
68 |
69 | 2. Add the StomtPlugin to your projects `PublicDependencyModuleNames` in the projects `build.cs`. `/Source/[YourProjectName]/[YourProjectName].Build.cs`:
70 | ```c++
71 | PublicDependencyModuleNames.AddRange(new string[] { "StomtPlugin" }); // Add "StomtPlugin" String
72 | ```
73 |
74 | 3. Restart Unreal Editor, open your project and enable the plugin. `Edit -> Plugins -> Widgets -> StomtPlugin`
75 |
76 | 4. Check `Show Plugin Content` and `Show Engine Content` in the bottom right corner of your editor (view options).
77 |
78 |
79 |
80 | 5. Place the `ExampleActor` in your scene.
81 |
82 | 6. Click play to run the game and show the feedback widget by pressing `E`.
83 |
84 | _You should now see the feedback form window in your game. Try to toggle "I wish"/"I like" and send a test stomt to "My Game" (The default test target). Then continue with [Configuration](#configuration)._
85 |
86 |
87 | ## Configuration
88 |
89 | 1. Create a page for your game on [www.stomt.com](https://www.stomt.com/signup/game).
90 |
91 | 2. Create an [App Id](https://www.stomt.com/integrate) for Unreal.
92 |
93 | 3. Enter the `App Id` into the `ExampleActor` Blueprint:
94 |
95 |
96 |
97 | **You can disable the screenshot and log-upload functionality**
98 |
99 |
100 |
101 | 4. Add the `StomtWidgetBP` to the viewport via script (`ExampleActor`) or in your main HUD (`ExampleUI`) as widget.
102 |
103 |
104 | ## Form Triggers
105 |
106 | The widget can be opened and closed whenever you want by using our trigger functions.
107 |
108 | That allows you to:
109 | * Put a button into the main menu [(Example)](https://imgur.com/5SoQzfj)
110 | * Put a button into the HUD [(Example)](https://imgur.com/t9wPpJj)
111 | * Only show the button to certain players (e.g. power users)
112 | * Trigger the form after certain events
113 |
114 | **Define a hotkey:**
115 |
116 |
117 |
118 |
119 | ## Event-Callbacks
120 |
121 | The STOMT Widget supports a variety of callback events.
122 |
123 |
124 |
125 | ## In-Game Labeling
126 |
127 | Labels will help you track down user issues.
128 | Append labels, as for example your game-version or the player position/level. You can either hardcode them in the Unity Inspector or use a script to add them in a flexible way based on the information you have.
129 |
130 |
131 |
132 |
133 |
134 | **Easily add an array of labels**
135 |
136 |
137 |
138 | ## Issues
139 |
140 | Don't hesitate to [contact](https://www.stomt.com/stomt-unreal-engine-plugin) us if you have any issues or need help.
141 |
142 | ## Versioning
143 |
144 | We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/stomt/stomt-unreal-plugin/tags).
145 |
146 | ## Contribution
147 |
148 | We would love to see you contributing to this project. Please read [CONTRIBUTING.md](https://github.com/stomt/stomt-unreal-plugin/blob/master/CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us.
149 |
150 | Visit the [project on STOMT](https://www.stomt.com/stomt-unreal-plugin) to support with your ideas, wishes and feedback.
151 |
152 | ## Authors
153 |
154 | [Daniel Schukies](https://github.com/daniel-schukies) | [Follow Daniel Schukies on STOMT](https://www.stomt.com/danielschukies)
155 |
156 | See also the list of [contributors](https://github.com/stomt/stomt-unreal-engine-plugin/contributors) who participated in this project.
157 |
158 | ## More about stomt
159 |
160 | *Regularly communicate your page on social channels and checkout our [Website-Widget](https://www.stomt.com/dev/js-sdk) for your websites to collect feedback from anywhere.*
161 |
162 | * On the web [www.stomt.com](https://www.stomt.com)
163 | * [STOMT for iOS](http://stomt.co/ios)
164 | * [STOMT for Android](http://stomt.co/android)
165 | * [STOMT for Unity](http://stomt.co/unity)
166 | * [STOMT for Websites](http://stomt.co/web)
167 | * [STOMT for Wordpress](http://stomt.co/wordpress)
168 | * [STOMT for Drupal](http://stomt.co/drupal)
169 |
--------------------------------------------------------------------------------
/Resources/Icon128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Resources/Icon128.png
--------------------------------------------------------------------------------
/Resources/languages.json:
--------------------------------------------------------------------------------
1 | {
2 | "data":
3 | {
4 | "de":
5 | {
6 | "SDK_STOMT_WISH_BUBBLE": "Ich wünschte",
7 | "SDK_STOMT_LIKE_BUBBLE": "Ich mag",
8 | "SDK_STOMT_DEFAULT_TEXT_WISH": "würde",
9 | "SDK_STOMT_DEFAULT_TEXT_LIKE": "weil",
10 | "SDK_STOMT_PLACEHOLDER": "...bitte beende diesen Satz",
11 | "SDK_STOMT_ERROR_MORE_TEXT": "Bitte schreibe etwas mehr.",
12 | "SDK_STOMT_ERROR_LESS_TEXT": "Nutze nur {0} Zeichen.",
13 | "SDK_STOMT_SCREENSHOT": "Screenshot",
14 |
15 | "SDK_HEADER_TARGET_STOMTS": "STOMTS",
16 | "SDK_HEADER_YOUR_STOMTS": "DEINE",
17 |
18 | "SDK_SUBSCRIBE_GET_NOTIFIED": "Abonniere STOMT um über Antworten auf Deinen Wunsch informiert zu werden.",
19 | "SDK_SUBSCRIBE_TOGGLE_EMAIL": "E-Mail",
20 | "SDK_SUBSCRIBE_TOGGLE_PHONE": "SMS",
21 | "SDK_SUBSCRIBE_EMAIL_QUESTION": "Wie lautet deine E-Mail-Adresse?",
22 | "SDK_SUBSCRIBE_PHONE_QUESTION": "Wie lautet deine Telefonnummer?",
23 | "SDK_SUBSCRIBE_PHONE_PLACEHOLDER" : "+49 152 03959902",
24 | "SDK_SUBSCRIBE_EMAIL_PLACEHOLDER" : "deine@email.com",
25 | "SDK_SUBSCRIBE_DEFAULT_PLACEHOLDER" : "Wir senden dir keine Spam Nachrichten",
26 | "SDK_SUBSCRIBE_VALID_EMAIL" : "E-Mail-Adresse ist gültig, fantastisch!",
27 | "SDK_SUBSCRIBE_NO_VALID_EMAIL" : "Bitte gebe eine gültige Adresse ein.",
28 | "SDK_SUBSCRIBE_SKIP": "Überspringen",
29 |
30 | "SDK_SUCCESS_THANK_YOU": "DANKE!",
31 | "SDK_SUCCESS_FIND_ALL_STOMTS": "Super, finde mehr Wünsche auf",
32 | "SDK_SUCCESS_FIND_YOUR_STOMTS": "Finde deine stomts",
33 | "SDK_SUCCESS_CREATE_NEW_WISH": "Wünsch dir noch was",
34 |
35 | "SDK_NETWORK_NOT_CONNECTED": "Verbindung zu STOMT unterbrochen",
36 | "SDK_NETWORK_NO_INTERNET": "Keine Internetverbindung",
37 | "SDK_NETWORK_RECONNECT": "Wiederverbinden",
38 |
39 | "SDK_LOGIN_ACCOUNT_WRONG": "Account Name stimmt nicht.",
40 | "SDK_LOGIN_PASSWORD_WRONG": "Passwort stimmt nicht.",
41 | "SDK_LOGIN_PASSWORD": "Passwort",
42 | "SDK_LOGIN": "Login",
43 | "SDK_LOGIN_SIGNUP": "Anmelden",
44 | "SDK_LOGIN_LOGOUT": "Ausloggen",
45 | "SDK_LOGIN_FORGOT_PW": "Passwort vergessen?",
46 | "SDK_LOGIN_SUCCESS": "Du bist eingeloggt!",
47 | "SDK_LOGIN_WENT_WRONG": "Ups, da lief was schief.",
48 |
49 | "SDK_ADD_DETAILS": "Mehr Text",
50 |
51 | "SDK_TERMS_LOGS_OPT_IN": "Dürfen wir Log-Dateien mitsenden?",
52 | "SDK_TERMS_LOGS_OPT_IN_DIS": "Nein, bitte nicht.",
53 | "SDK_TERMS_LOGS_OPT_OUT": "Wir werden Log-Dateien anhängen.",
54 | "SDK_TERMS_LOGS_OPT_OUT_DIS": "Keine Log-Dateien anhängen."
55 | },
56 | "en":
57 | {
58 | "SDK_STOMT_WISH_BUBBLE": "I wish",
59 | "SDK_STOMT_LIKE_BUBBLE": "I like",
60 | "SDK_STOMT_DEFAULT_TEXT_WISH": "would",
61 | "SDK_STOMT_DEFAULT_TEXT_LIKE": "because",
62 | "SDK_STOMT_PLACEHOLDER": "...please finish the sentence",
63 | "SDK_STOMT_ERROR_MORE_TEXT": "Please write a bit more.",
64 | "SDK_STOMT_ERROR_LESS_TEXT": "Use only {0} characters.",
65 | "SDK_STOMT_SCREENSHOT": "Screenshot",
66 |
67 | "SDK_HEADER_TARGET_STOMTS": "STOMTS",
68 | "SDK_HEADER_YOUR_STOMTS": "YOURS",
69 |
70 | "SDK_SUBSCRIBE_GET_NOTIFIED": "Subscribe to STOMT to get notified about responses to your wish.",
71 | "SDK_SUBSCRIBE_TOGGLE_EMAIL": "E-Mail",
72 | "SDK_SUBSCRIBE_TOGGLE_PHONE": "SMS",
73 | "SDK_SUBSCRIBE_EMAIL_QUESTION": "What's your email address?",
74 | "SDK_SUBSCRIBE_PHONE_QUESTION": "What's your phone number?",
75 | "SDK_SUBSCRIBE_PHONE_PLACEHOLDER" : "+1-541-754-3010",
76 | "SDK_SUBSCRIBE_EMAIL_PLACEHOLDER" : "your@gmail.com",
77 | "SDK_SUBSCRIBE_DEFAULT_PLACEHOLDER" : "We won’t share your contact nor spam you.",
78 | "SDK_SUBSCRIBE_VALID_EMAIL" : "Email address is valid, fantastic!",
79 | "SDK_SUBSCRIBE_NO_VALID_EMAIL" : "Please type in a valid address.",
80 | "SDK_SUBSCRIBE_SKIP": "Skip",
81 |
82 | "SDK_SUCCESS_THANK_YOU": "THANK YOU!",
83 | "SDK_SUCCESS_FIND_ALL_STOMTS": "Amazing, find more wishes on",
84 | "SDK_SUCCESS_FIND_YOUR_STOMTS": "click to find your stomts here",
85 | "SDK_SUCCESS_CREATE_NEW_WISH": "Create another wish",
86 |
87 | "SDK_NETWORK_NOT_CONNECTED": "Could not connect to STOMT",
88 | "SDK_NETWORK_NO_INTERNET": "No internet connection",
89 | "SDK_NETWORK_RECONNECT": "Reconnect",
90 |
91 | "SDK_LOGIN_ACCOUNT_WRONG": "Account was incorrect.",
92 | "SDK_LOGIN_PASSWORD_WRONG": "Password was incorrect.",
93 | "SDK_LOGIN_PASSWORD": "Password",
94 | "SDK_LOGIN": "Login",
95 | "SDK_LOGIN_SIGNUP": "Signup",
96 | "SDK_LOGIN_LOGOUT": "Logout",
97 | "SDK_LOGIN_FORGOT_PW": "Forgot password?",
98 | "SDK_LOGIN_SUCCESS": "You're now logged in!",
99 | "SDK_LOGIN_WENT_WRONG": "Ups something went wrong.",
100 |
101 | "SDK_ADD_DETAILS": "More Text",
102 |
103 | "SDK_TERMS_LOGS_OPT_IN": "May we attach log files?",
104 | "SDK_TERMS_LOGS_OPT_IN_DIS": "No, please don't.",
105 | "SDK_TERMS_LOGS_OPT_OUT": "We will attach log files to your stomt.",
106 | "SDK_TERMS_LOGS_OPT_OUT_DIS": "Do not attach log files."
107 | },
108 | "es":
109 | {
110 | "SDK_STOMT_WISH_BUBBLE": "Quiero que",
111 | "SDK_STOMT_LIKE_BUBBLE": "Me gusta",
112 | "SDK_STOMT_DEFAULT_TEXT_WISH": "haga",
113 | "SDK_STOMT_DEFAULT_TEXT_LIKE": "porque",
114 | "SDK_STOMT_PLACEHOLDER": "... por favor termine la frase",
115 | "SDK_STOMT_ERROR_MORE_TEXT": "Por favor escriba un poco más",
116 | "SDK_STOMT_SCREENSHOT": "Captura de pantalla",
117 | "SDK_HEADER_TARGET_STOMTS": "STOMTS",
118 | "SDK_HEADER_YOUR_STOMTS": "TUYOS",
119 | "SDK_SUBSCRIBE_GET_NOTIFIED": "Suscríbete a STOMT para obtener respuestas.",
120 | "SDK_SUBSCRIBE_TOGGLE_EMAIL": "Correo",
121 | "SDK_SUBSCRIBE_TOGGLE_PHONE": "SMS",
122 | "SDK_SUBSCRIBE_EMAIL_QUESTION": "¿Cuál es tu dirección de correo electrónico?",
123 | "SDK_SUBSCRIBE_PHONE_QUESTION": "¿Cuál es tu número de teléfono?",
124 | "SDK_SUBSCRIBE_PHONE_PLACEHOLDER": "+ 1-541-754-3010",
125 | "SDK_SUBSCRIBE_EMAIL_PLACEHOLDER": "your@gmail.com",
126 | "SDK_SUBSCRIBE_SKIP": "Omitir",
127 | "SDK_SUCCESS_THANK_YOU": "¡GRACIAS!",
128 | "SDK_SUCCESS_FIND_ALL_STOMTS": "Increíble, encuentra más deseos en",
129 | "SDK_SUCCESS_FIND_YOUR_STOMTS": "haga clic para encontrar sus stomts aquí",
130 | "SDK_SUCCESS_CREATE_NEW_WISH": "Crea otra petición",
131 | "SDK_NETWORK_NOT_CONNECTED": "No se pudo conectar con STOMT",
132 | "SDK_NETWORK_NO_INTERNET": "No hay conexión a Internet",
133 | "SDK_NETWORK_RECONNECT": "Reconectar",
134 | "SDK_LOGIN": "Login",
135 | "SDK_LOGIN_LOGOUT": "Logout"
136 | },
137 | "it":
138 | {
139 | "SDK_STOMT_WISH_BUBBLE": "Vorrei che",
140 | "SDK_STOMT_LIKE_BUBBLE": "Mi piace",
141 | "SDK_STOMT_DEFAULT_TEXT_WISH": "che",
142 | "SDK_STOMT_DEFAULT_TEXT_LIKE": "perché",
143 | "SDK_STOMT_PLACEHOLDER": "... completa la frase perfavore",
144 | "SDK_STOMT_ERROR_MORE_TEXT": "Scrivi un po 'di più perfavore.",
145 | "SDK_STOMT_SCREENSHOT": "Screenshot",
146 | "SDK_HEADER_TARGET_STOMTS": "STOMTS",
147 | "SDK_HEADER_YOUR_STOMTS": "IL TUO",
148 | "SDK_SUBSCRIBE_GET_NOTIFIED": "Iscriviti a STOMT per le risposte.",
149 | "SDK_SUBSCRIBE_TOGGLE_EMAIL": "E-Mail",
150 | "SDK_SUBSCRIBE_TOGGLE_PHONE": "SMS",
151 | "SDK_SUBSCRIBE_EMAIL_QUESTION": "Qual è il tuo indirizzo e-mail?",
152 | "SDK_SUBSCRIBE_PHONE_QUESTION": "Qual è il tuo numero di telefono?",
153 | "SDK_SUBSCRIBE_PHONE_PLACEHOLDER": "+ 1-541-754-3010",
154 | "SDK_SUBSCRIBE_EMAIL_PLACEHOLDER": "latuaemail@gmail.com",
155 | "SDK_SUBSCRIBE_SKIP": "Salta",
156 | "SDK_SUCCESS_THANK_YOU": "GRAZIE!",
157 | "SDK_SUCCESS_FIND_ALL_STOMTS": "Magnifico, trova più desideri",
158 | "SDK_SUCCESS_FIND_YOUR_STOMTS": "clicca qui per trovare i tuoi stomt",
159 | "SDK_SUCCESS_CREATE_NEW_WISH": "Crea un altro desiderio",
160 | "SDK_NETWORK_NOT_CONNECTED": "Impossibile connettersi a STOMT",
161 | "SDK_NETWORK_NO_INTERNET": "Nessuna connessione internet",
162 | "SDK_NETWORK_RECONNECT": "Ricollegati",
163 | "SDK_LOGIN": "Login",
164 | "SDK_LOGIN_LOGOUT": "Logout"
165 | },
166 | "pt":
167 | {
168 | "SDK_STOMT_WISH_BUBBLE": "Eu gostaria que",
169 | "SDK_STOMT_LIKE_BUBBLE": "Eu gosto de",
170 | "SDK_STOMT_DEFAULT_TEXT_WISH": "",
171 | "SDK_STOMT_DEFAULT_TEXT_LIKE": "porque",
172 | "SDK_STOMT_PLACEHOLDER": "... por favor termine a frase",
173 | "SDK_STOMT_ERROR_MORE_TEXT": "Escreva um pouco mais.",
174 | "SDK_STOMT_SCREENSHOT": "Captura de tela",
175 | "SDK_HEADER_TARGET_STOMTS": "STOMTS",
176 | "SDK_HEADER_YOUR_STOMTS": "SUA",
177 | "SDK_SUBSCRIBE_GET_NOTIFIED": "Assine o STOMT para respostas.",
178 | "SDK_SUBSCRIBE_TOGGLE_EMAIL": "E-Mail",
179 | "SDK_SUBSCRIBE_TOGGLE_PHONE": "SMS",
180 | "SDK_SUBSCRIBE_EMAIL_QUESTION": "Qual é o seu e-mail?",
181 | "SDK_SUBSCRIBE_PHONE_QUESTION": "Qual é o seu número de telefone?",
182 | "SDK_SUBSCRIBE_PHONE_PLACEHOLDER": "+ 1-541-754-3010",
183 | "SDK_SUBSCRIBE_EMAIL_PLACEHOLDER": "your@gmail.com",
184 | "SDK_SUBSCRIBE_SKIP": "Pular",
185 | "SDK_SUCCESS_THANK_YOU": "OBRIGADO!",
186 | "SDK_SUCCESS_FIND_ALL_STOMTS": "Incrível, encontre mais stomts sobre",
187 | "SDK_SUCCESS_FIND_YOUR_STOMTS": "Clique aqui para encontrar seus stomts",
188 | "SDK_SUCCESS_CREATE_NEW_WISH": "Criar outro stomt",
189 | "SDK_NETWORK_NOT_CONNECTED": "Não foi possível conectar-se ao STOMT",
190 | "SDK_NETWORK_NO_INTERNET": "Sem conexão à internet",
191 | "SDK_NETWORK_RECONNECT": "Reconectar",
192 | "SDK_LOGIN": "Login",
193 | "SDK_LOGIN_LOGOUT": "Logout"
194 | }
195 | }
196 | }
--------------------------------------------------------------------------------
/Source/StomtPlugin/Private/Stomt.cpp:
--------------------------------------------------------------------------------
1 | // Copyright 2018 STOMT GmbH. All Rights Reserved.
2 | #pragma once
3 |
4 | #include "Stomt.h"
5 | #include "StomtPluginPrivatePCH.h"
6 |
7 | //////////////////////////////////////////////////////////////////////////
8 | // Construction
9 |
10 | UStomt::UStomt()
11 | {
12 |
13 | }
14 |
15 | UStomt* UStomt::ConstructStomt(FString NewTargetId, bool bNewPositive, FString NewText, FString NewDetails)
16 | {
17 | UStomt* NewStomt = NewObject();
18 | NewStomt->SetTargetId(NewTargetId);
19 | NewStomt->SetPositive(bNewPositive);
20 | NewStomt->SetText(NewText);
21 | NewStomt->SetDetails(NewDetails);
22 |
23 | return NewStomt;
24 | }
25 |
26 | //////////////////////////////////////////////////////////////////////////
27 | // Data accessors
28 |
29 | void UStomt::SetTargetId(FString NewTargetId)
30 | {
31 | this->TargetId = NewTargetId;
32 | }
33 |
34 | void UStomt::SetPositive(bool bNewPositive)
35 | {
36 | this->bPositive = bNewPositive;
37 | }
38 |
39 | void UStomt::SetText(FString NewText)
40 | {
41 | this->Text = NewText;
42 | }
43 |
44 | void UStomt::SetDetails(FString NewDetails)
45 | {
46 | this->Details = NewDetails;
47 | }
48 |
49 | void UStomt::SetAnonym(bool bNewAnonym)
50 | {
51 | this->bAnonym = bNewAnonym;
52 | }
53 |
54 | void UStomt::SetServersideId(FString NewServersideId)
55 | {
56 | this->ServersideId = NewServersideId;
57 | }
58 |
59 | void UStomt::AddLabel(UStomtLabel* newLabel)
60 | {
61 | this->Labels.Add(newLabel);
62 | }
63 | void UStomt::SetLabels(TArray NewLabels)
64 | {
65 | this->Labels = NewLabels;
66 | }
67 |
68 | void UStomt::SetLabels(TArray NewLabels)
69 | {
70 | if (NewLabels.Num() <= 0)
71 | return;
72 |
73 | this->Labels.Empty();
74 |
75 | for (int i = 0; i != NewLabels.Num(); ++i)
76 | {
77 | this->Labels.Add(UStomtLabel::ConstructLabel(NewLabels[i]));
78 | }
79 | }
80 |
81 | FString UStomt::GetTargetId()
82 | {
83 | return this->TargetId;
84 | }
85 |
86 | bool UStomt::GetPositive()
87 | {
88 | return this->bPositive;
89 | }
90 |
91 | FString UStomt::GetText()
92 | {
93 | return this->Text;
94 | }
95 |
96 |
97 | FString UStomt::GetDetails()
98 | {
99 | return this->Details;
100 | }
101 |
102 | bool UStomt::GetAnonym()
103 | {
104 | return this->bAnonym;
105 | }
106 | TArray UStomt::GetLabels()
107 | {
108 | return this->Labels;
109 | }
110 |
111 | FString UStomt::GetServersideId()
112 | {
113 | return this->ServersideId;
114 | }
115 |
--------------------------------------------------------------------------------
/Source/StomtPlugin/Private/StomtAPI.cpp:
--------------------------------------------------------------------------------
1 | // Copyright 2018 STOMT GmbH. All Rights Reserved.
2 | #pragma once
3 |
4 | #include "StomtAPI.h"
5 | #include "StomtPluginPrivatePCH.h"
6 | #include "StomtJsonObject.h"
7 |
8 | #include "Runtime/Engine/Public/HighResScreenshot.h"
9 | #include "Runtime/Core/Public/Misc/FileHelper.h"
10 | #include "Runtime/Core/Public/Misc/Paths.h"
11 | #include "Runtime/Core/Public/GenericPlatform/GenericPlatformFile.h"
12 | #include "Runtime/Core/Public/Misc/Base64.h"
13 | #include "Runtime/Core/Public/Misc/App.h"
14 | #include "Runtime/Core/Public/Internationalization/Regex.h"
15 |
16 | //////////////////////////////////////////////////////////////////////////
17 | // Constructors
18 |
19 | UStomtAPI* UStomtAPI::ConstructStomtAPI(FString NewAppId)
20 | {
21 | UStomtAPI* Api = NewObject();
22 |
23 | Api->SetAppId(NewAppId);
24 |
25 | UE_LOG(StomtInit, Log, TEXT("Construct Stomt API"));
26 | UE_LOG(StomtInit, Log, TEXT("AppId: %s "), *Api->GetAppId());
27 | UE_LOG(StomtInit, Log, TEXT("RestUrl: %s "), *Api->GetRestUrl());
28 |
29 | Api->LoadLanguageFile();
30 |
31 | UE_LOG(StomtInit, Log, TEXT("LangTest: %s"), *Api->GetLangText("SDK_STOMT_WISH_BUBBLE"));
32 |
33 | return Api;
34 | }
35 |
36 | UStomtAPI::UStomtAPI()
37 | {
38 | this->bLogFileWasSend = false;
39 | this->bEMailFlagWasSend = false;
40 | this->bIsImageUploadComplete = false;
41 | this->bIsLogUploadComplete = false;
42 | this->bUseImageUpload = true;
43 | this->bUseDefaultLabels = true;
44 | this->bNetworkError = false;
45 |
46 | this->DefaultScreenshotName = FString("HighresScreenshot00000.png");
47 | this->Config = UStomtConfig::ConstructStomtConfig();
48 | this->Track = UStomtTrack::ConstructStomtTrack();
49 | this->SetCurrentLanguage(this->GetSystemLanguage());
50 | }
51 |
52 | UStomtAPI::~UStomtAPI()
53 | {
54 | }
55 |
56 |
57 | //////////////////////////////////////////////////////////////////////////
58 | // Data accessors
59 |
60 | void UStomtAPI::SetRestUrl(FString NewRestUrl)
61 | {
62 | this->RestUrl = NewRestUrl;
63 | }
64 |
65 | FString UStomtAPI::GetRestUrl()
66 | {
67 | return this->RestUrl;
68 | }
69 |
70 | void UStomtAPI::SetStomtUrl(FString NewStomtUrl)
71 | {
72 | this->StomtUrl = NewStomtUrl;
73 | }
74 |
75 | FString UStomtAPI::GetStomtUrl()
76 | {
77 | return this->StomtUrl;
78 | }
79 |
80 | void UStomtAPI::SetAppId(FString NewAppId)
81 | {
82 | if (NewAppId.Equals("Copy_your_AppId_here") || NewAppId.Equals("AKN5M7Ob0MqxKXYdE9i3IhQtF") || NewAppId.Equals(""))
83 | {
84 | this->AppId = "AKN5M7Ob0MqxKXYdE9i3IhQtF";
85 | this->SetRestUrl("https://test.rest.stomt.com");
86 | this->SetStomtUrl("https://test.stomt.com/");
87 | }
88 | else
89 | {
90 | this->AppId = NewAppId;
91 | this->SetRestUrl("https://rest.stomt.com");
92 | this->SetStomtUrl("https://www.stomt.com/");
93 | }
94 | }
95 |
96 | FString UStomtAPI::GetAppId()
97 | {
98 | return this->AppId;
99 | }
100 |
101 | FString UStomtAPI::GetTargetName()
102 | {
103 | return this->TargetName;
104 | }
105 |
106 | void UStomtAPI::SetTargetId(FString NewTargetId)
107 | {
108 | this->TargetId = NewTargetId;
109 | }
110 |
111 | FString UStomtAPI::GetTargetId()
112 | {
113 | return this->TargetId;
114 | }
115 |
116 | void UStomtAPI::SetImageUrl(FString NewImageUrl)
117 | {
118 | this->ImageUrl = NewImageUrl;
119 | }
120 |
121 | FString UStomtAPI::GetImageUrl()
122 | {
123 | return this->ImageUrl;
124 | }
125 |
126 | void UStomtAPI::SetStomtToSend(UStomt * NewStomt)
127 | {
128 | this->StomtToSend = NewStomt;
129 | }
130 |
131 | FString UStomtAPI::GetCurrentLanguage()
132 | {
133 | return this->CurrentLanguage;
134 | }
135 |
136 | bool UStomtAPI::SetCurrentLanguage(FString Language)
137 | {
138 | if (Language.IsEmpty())
139 | return false;
140 |
141 | this->CurrentLanguage = Language.Left(2);
142 |
143 | return true;
144 | }
145 |
146 | FString UStomtAPI::GetSystemLanguage()
147 | {
148 | return FInternationalization::Get().GetCurrentCulture()->GetName().Left(2);
149 | }
150 |
151 | bool UStomtAPI::IsConnected()
152 | {
153 | return !bNetworkError;
154 | }
155 |
156 |
157 | //////////////////////////////////////////////////////////////////////////
158 | // Helpers: Request
159 |
160 | UStomtRestRequest* UStomtAPI::SetupNewRequest(StomtEnumRequestVerb::Type Verb)
161 | {
162 | UStomtRestRequest* Request = NewObject();
163 | Request->OnRequestFail.AddDynamic(this, &UStomtAPI::OnARequestFailed);
164 | Request->OnRequestComplete.AddDynamic(this, &UStomtAPI::ParseAccessTokenFromResponse);
165 |
166 | Request->SetVerb(Verb);
167 | Request->SetHeader(TEXT("appid"), this->GetAppId());
168 | this->AddAccesstokenToRequest(Request);
169 |
170 | return Request;
171 | }
172 |
173 | void UStomtAPI::AddAccesstokenToRequest(UStomtRestRequest * Request)
174 | {
175 | if (!this->Config->GetAccessToken().IsEmpty())
176 | {
177 | Request->SetHeader(TEXT("accesstoken"), this->Config->GetAccessToken());
178 | }
179 | }
180 |
181 | void UStomtAPI::OnARequestFailed(UStomtRestRequest * Request)
182 | {
183 | this->bNetworkError = true;
184 | this->OnRequestFailed.Broadcast(Request);
185 | }
186 |
187 | void UStomtAPI::ParseAccessTokenFromResponse(UStomtRestRequest * Request)
188 | {
189 | if (!Request->GetResponseObject()->HasField(TEXT("meta"))) return;
190 | if (!Request->GetResponseObject()->HasField(TEXT("meta"))) return;
191 | if (!Request->GetResponseObject()->GetObjectField(TEXT("meta"))->HasField(TEXT("accesstoken"))) return;
192 |
193 | FString Accesstoken = Request->GetResponseObject()->GetObjectField(TEXT("meta"))->GetStringField(TEXT("accesstoken"));
194 | if (Accesstoken.Equals(this->Config->GetAccessToken())) return;
195 |
196 | this->Config->SetAccessToken(Accesstoken);
197 | this->RequestSession();
198 | }
199 |
200 |
201 | //////////////////////////////////////////////////////////////////////////
202 | // Requests
203 |
204 |
205 | void UStomtAPI::SendStomt(UStomt* NewStomt)
206 | {
207 | if (!this->IsConnected())
208 | {
209 | this->Config->AddStomt(NewStomt);
210 | return;
211 | }
212 |
213 | UStomtRestRequest* Request = this->SetupNewRequest(StomtEnumRequestVerb::POST);
214 | Request->OnRequestComplete.AddDynamic(this, &UStomtAPI::OnSendStomtRequestResponse);
215 |
216 | // Fields
217 | Request->GetRequestObject()->SetField(TEXT("target_id"), UStomtJsonValue::ConstructJsonValueString(this, NewStomt->GetTargetId()));
218 | Request->GetRequestObject()->SetField(TEXT("positive"), UStomtJsonValue::ConstructJsonValueBool(this, NewStomt->GetPositive()));
219 | Request->GetRequestObject()->SetField(TEXT("text"), UStomtJsonValue::ConstructJsonValueString(this, NewStomt->GetText()));
220 | Request->GetRequestObject()->SetField(TEXT("details"), UStomtJsonValue::ConstructJsonValueString(this, NewStomt->GetDetails()));
221 | Request->GetRequestObject()->SetField(TEXT("anonym"), UStomtJsonValue::ConstructJsonValueBool(this, NewStomt->GetAnonym()));
222 |
223 | // Labels
224 | UStomtRestJsonObject* JObjExtraData = UStomtRestJsonObject::ConstructJsonObject(this);
225 | TArray Labels = TArray();
226 |
227 | for (int i = 0; i != NewStomt->GetLabels().Num(); ++i)
228 | {
229 | if (!NewStomt->GetLabels()[i]->GetName().IsEmpty())
230 | {
231 | Labels.Add(UStomtJsonValue::ConstructJsonValueString(this, NewStomt->GetLabels()[i]->GetName()));
232 | }
233 | }
234 |
235 | if (this->bUseDefaultLabels)
236 | {
237 | const FVector2D ViewportSize = FVector2D(GEngine->GameViewport->Viewport->GetSizeXY());
238 | Labels.Add(UStomtJsonValue::ConstructJsonValueString(this, ViewportSize.ToString()));
239 | Labels.Add(UStomtJsonValue::ConstructJsonValueString(this, UGameplayStatics::GetPlatformName()));
240 | }
241 |
242 | if (Labels.Num() > 0)
243 | {
244 | JObjExtraData->SetArrayField(TEXT("labels"), Labels);
245 | Request->GetRequestObject()->SetObjectField(TEXT("extradata"), JObjExtraData);
246 | }
247 |
248 | if (this->CustomKeyValuePairs.Num() > 0)
249 | {
250 | for (int i = 0; i != this->CustomKeyValuePairs.Num(); ++i)
251 | {
252 | JObjExtraData->SetStringField(this->CustomKeyValuePairs[i][0], this->CustomKeyValuePairs[i][1]);
253 | }
254 | }
255 |
256 | // Stomt Image
257 | if (!this->ImageUploadName.IsEmpty() && this->bUseImageUpload)
258 | {
259 | Request->GetRequestObject()->SetStringField(TEXT("img_name"), this->ImageUploadName);
260 | UE_LOG(StomtNetwork, Log, TEXT("Append Image"));
261 | }
262 | else
263 | {
264 | UE_LOG(StomtNetwork, Log, TEXT("Append no Image (Don't use image upload)"));
265 | }
266 |
267 | // Error Logs
268 | if (!this->ErrorLogFileUid.IsEmpty())
269 | {
270 | UStomtRestJsonObject* JObjFile = UStomtRestJsonObject::ConstructJsonObject(this);
271 | UStomtRestJsonObject* JObjFileContext = UStomtRestJsonObject::ConstructJsonObject(this);
272 | JObjFileContext->SetField(TEXT("file_uid"), UStomtJsonValue::ConstructJsonValueString(this, this->ErrorLogFileUid));
273 |
274 | JObjFile->SetObjectField(TEXT("stomt"), JObjFileContext);
275 | Request->GetRequestObject()->SetObjectField(TEXT("files"), JObjFile);
276 | }
277 |
278 | Request->ProcessUrl(this->GetRestUrl().Append(TEXT("/stomts")));
279 | }
280 |
281 | void UStomtAPI::OnSendStomtRequestResponse(UStomtRestRequest * Request)
282 | {
283 | if (Request->GetResponseCode() == 200)
284 | {
285 | if (Request->GetResponseObject()->HasField(TEXT("data")))
286 | {
287 | if (Request->GetResponseObject()->GetObjectField(TEXT("data"))->HasField(TEXT("id")))
288 | {
289 | FString Id = Request->GetResponseObject()->GetObjectField(TEXT("data"))->GetStringField(TEXT("id"));
290 | this->Track->SetStomtId(Id);
291 | this->Track->SetEventCategory("stomt");
292 | this->Track->SetEventAction("submit");
293 | this->SendTrack(this->Track);
294 | return;
295 | }
296 | }
297 | }
298 |
299 | UE_LOG(StomtNetwork, Warning, TEXT("Send Stomt did not work | OnSendStomtRequestResponse"));
300 | }
301 |
302 | UStomtRestRequest* UStomtAPI::SendLoginRequest(FString UserName, FString Password)
303 | {
304 | UStomtRestRequest* Request = this->SetupNewRequest(StomtEnumRequestVerb::POST);
305 | Request->OnRequestComplete.AddDynamic(this, &UStomtAPI::OnLoginRequestResponse);
306 |
307 | Request->UseRequestLogging(false);
308 |
309 | Request->GetRequestObject()->SetStringField(TEXT("login_method"), TEXT("normal"));
310 | Request->GetRequestObject()->SetStringField(TEXT("emailusername"), UserName);
311 | Request->GetRequestObject()->SetStringField(TEXT("password"), Password);
312 |
313 | Request->ProcessUrl(this->GetRestUrl().Append(TEXT("/authentication/session")));
314 |
315 | Request->UseRequestLogging(true);
316 |
317 | return Request;
318 | }
319 |
320 | void UStomtAPI::OnLoginRequestResponse(UStomtRestRequest * Request)
321 | {
322 | if (Request->GetResponseCode() != 200) return;
323 | if (!Request->GetResponseObject()->HasField(TEXT("data"))) return;
324 | if (!Request->GetResponseObject()->GetObjectField(TEXT("data"))->HasField(TEXT("accesstoken"))) return;
325 |
326 | this->Config->SetSubscribed(true);
327 | this->Config->SetLoggedIn(true);
328 |
329 | this->Track->SetEventCategory("auth");
330 | this->Track->SetEventAction("login");
331 | this->SendTrack(this->Track);
332 | }
333 |
334 | UStomtRestRequest* UStomtAPI::RequestSession()
335 | {
336 | if (this->Config->GetAccessToken().IsEmpty()) return NULL;
337 |
338 | UStomtRestRequest* Request = SetupNewRequest(StomtEnumRequestVerb::GET);
339 | Request->OnRequestComplete.AddDynamic(this, &UStomtAPI::OnRequestSessionResponse);
340 | Request->ProcessUrl(this->GetRestUrl().Append("/authentication/session"));
341 |
342 | return Request;
343 | }
344 |
345 | void UStomtAPI::OnRequestSessionResponse(UStomtRestRequest * Request)
346 | {
347 | if (Request->GetResponseCode() == 419)
348 | {
349 | // Forbidden: Session invalid. (Request a new access-token via login or refresh token.)
350 | UE_LOG(StomtNetwork, Warning, TEXT("Invalid accesstoken."));
351 | Config->SetAccessToken("");
352 | return;
353 | }
354 |
355 | if (Request->GetResponseCode() != 200) return;
356 | if (!Request->GetResponseObject()->HasField(TEXT("data"))) return;
357 | if (!Request->GetResponseObject()->GetObjectField(TEXT("data"))->HasField(TEXT("user"))) return;
358 |
359 | this->StomtsCreatedByUser = (int)Request->GetResponseObject()->GetObjectField(TEXT("data"))->GetObjectField(TEXT("user"))->GetObjectField(TEXT("stats"))->GetNumberField(TEXT("amountStomtsCreated"));
360 | this->UserId = (FString)Request->GetResponseObject()->GetObjectField(TEXT("data"))->GetObjectField(TEXT("user"))->GetStringField("id");
361 |
362 | OnSessionRequestComplete.Broadcast(Request);
363 | UE_LOG(StomtNetwork, Log, TEXT("StomtsCreatedByUser: %d | StomtsReceivedByTarget: %d"), StomtsCreatedByUser, StomtsReceivedByTarget);
364 | }
365 |
366 | UStomtRestRequest* UStomtAPI::RequestTargetByAppId()
367 | {
368 | UStomtRestRequest* Request = SetupNewRequest(StomtEnumRequestVerb::GET);
369 | Request->OnRequestComplete.AddDynamic(this, &UStomtAPI::OnRequestTargetResponse);
370 | Request->ProcessUrl(this->GetRestUrl().Append("/targets/"));
371 |
372 | return Request;
373 | }
374 |
375 | UStomtRestRequest* UStomtAPI::RequestTarget(FString RequestedTargetId)
376 | {
377 | UStomtRestRequest* Request = SetupNewRequest(StomtEnumRequestVerb::GET);
378 | Request->OnRequestComplete.AddDynamic(this, &UStomtAPI::OnRequestTargetResponse);
379 | Request->ProcessUrl(this->GetRestUrl().Append("/targets/").Append(RequestedTargetId));
380 |
381 | return Request;
382 | }
383 |
384 | void UStomtAPI::OnRequestTargetResponse(UStomtRestRequest * Request)
385 | {
386 | if (Request->GetResponseCode() != 200) return;
387 | if (!Request->GetResponseObject()->HasField(TEXT("data"))) return;
388 | if (!Request->GetResponseObject()->GetObjectField(TEXT("data"))->HasField(TEXT("displayname"))) return;
389 |
390 | this->TargetName = Request->GetResponseObject()->GetObjectField(TEXT("data"))->GetStringField(TEXT("displayname"));
391 | this->TargetId = Request->GetResponseObject()->GetObjectField(TEXT("data"))->GetStringField(TEXT("id"));
392 | this->SetImageUrl(Request->GetResponseObject()
393 | ->GetObjectField(TEXT("data"))
394 | ->GetObjectField(TEXT("images"))
395 | ->GetObjectField(TEXT("profile"))
396 | ->GetStringField(TEXT("url")));
397 | this->StomtsReceivedByTarget = (int)Request->GetResponseObject()
398 | ->GetObjectField(TEXT("data"))
399 | ->GetObjectField(TEXT("stats"))
400 | ->GetNumberField(TEXT("amountStomtsReceived"));
401 | }
402 |
403 | void UStomtAPI::SendLogFile(FString LogFileData, FString LogFileName)
404 | {
405 | if (LogFileData.IsEmpty())
406 | {
407 | this->bIsLogUploadComplete = true;
408 | return;
409 | }
410 |
411 | UStomtRestRequest* Request = this->SetupNewRequest(StomtEnumRequestVerb::POST);
412 | Request->OnRequestComplete.AddDynamic(this, &UStomtAPI::OnSendLogFileResponse);
413 |
414 | FString LogJsonString = FString(TEXT("{ \"files\": { \"stomt\": [ { \"data\":\"") + FBase64::Encode(LogFileData) + TEXT("\", \"filename\" : \"") + LogFileName + TEXT("\" } ] } }"));
415 |
416 | Request->UseStaticJsonString(true);
417 | Request->SetStaticJsonString(LogJsonString);
418 |
419 | Request->ProcessUrl(this->GetRestUrl().Append(TEXT("/files")));
420 |
421 | this->bLogFileWasSend = true;
422 | }
423 |
424 | void UStomtAPI::OnSendLogFileResponse(UStomtRestRequest * Request)
425 | {
426 | // handle response
427 | this->bLogFileWasSend = false; // ????
428 | this->bIsLogUploadComplete = true; // ????
429 | if (Request->GetResponseObject()->HasField(TEXT("data")))
430 | {
431 | if (Request->GetResponseObject()->GetObjectField(TEXT("data"))->HasField(TEXT("files")))
432 | {
433 | this->ErrorLogFileUid = Request->GetResponseObject()->GetObjectField(TEXT("data"))->GetObjectField(TEXT("files"))->GetObjectField(TEXT("stomt"))->GetStringField("file_uid");
434 | UE_LOG(StomtNetwork, Log, TEXT("Log Upload complete %s"), *this->ErrorLogFileUid);
435 | }
436 | }
437 |
438 | // next step
439 | if (!this->bUseImageUpload && this->bIsImageUploadComplete) {
440 | this->SendStomt(this->StomtToSend);
441 | UE_LOG(StomtNetwork, Log, TEXT("Sent Stomt after sending log files"));
442 | } else {
443 | UE_LOG(StomtNetwork, Log, TEXT("Wait for image upload"));
444 | }
445 | }
446 |
447 | void UStomtAPI::SendImageFile(FString ImageFileDataBase64)
448 | {
449 | if (ImageFileDataBase64.IsEmpty())
450 | {
451 | UE_LOG(StomtNetwork, Warning, TEXT("Could not send stomt image | ImageFileDataBase64 was empty"));
452 | return;
453 | }
454 |
455 | UStomtRestRequest* Request = this->SetupNewRequest(StomtEnumRequestVerb::POST);
456 | Request->OnRequestComplete.AddDynamic(this, &UStomtAPI::OnSendImageFileResponse);
457 |
458 | Request->UseStaticJsonString(true);
459 | FString ImageJson = FString(TEXT("{ \"images\": { \"stomt\": [ { \"data\":\"") + ImageFileDataBase64 + TEXT("\" } ] } }"));
460 | Request->SetStaticJsonString(ImageJson);
461 |
462 | Request->ProcessUrl(this->GetRestUrl().Append(TEXT("/images")));
463 | }
464 |
465 | void UStomtAPI::OnSendImageFileResponse(UStomtRestRequest * Request)
466 | {
467 | // handle response
468 | this->bIsImageUploadComplete = true;
469 | if (Request->GetResponseObject()->HasField(TEXT("data")))
470 | {
471 | if (Request->GetResponseObject()->GetObjectField(TEXT("data"))->HasField(TEXT("images")))
472 | {
473 | this->ImageUploadName = Request->GetResponseObject()->GetObjectField(TEXT("data"))->GetObjectField(TEXT("images"))->GetObjectField(TEXT("stomt"))->GetStringField("name");
474 | UE_LOG(StomtNetwork, Log, TEXT("Image Upload complete %s"), *this->ImageUploadName);
475 | }
476 | }
477 |
478 | // next step
479 | if (this->bIsImageUploadComplete) {
480 | this->SendStomt(this->StomtToSend);
481 | UE_LOG(StomtNetwork, Log, TEXT("Sent Stomt after sending image files"));
482 | } else {
483 | UE_LOG(StomtNetwork, Log, TEXT("Wait for log upload"));
484 | }
485 | }
486 |
487 | void UStomtAPI::SendSubscription(FString EMail)
488 | {
489 | SendSubscription(EMail, false);
490 | }
491 |
492 | void UStomtAPI::SendSubscription(FString EMailOrNumber, bool bUseEmail)
493 | {
494 | UStomtRestRequest* Request = this->SetupNewRequest(StomtEnumRequestVerb::POST);
495 | Request->OnRequestComplete.AddDynamic(this, &UStomtAPI::UStomtAPI::OnSendEMailResponse);
496 |
497 | if (bUseEmail)
498 | {
499 | Request->GetRequestObject()->SetStringField(TEXT("email"), EMailOrNumber);
500 | }
501 | else
502 | {
503 | Request->GetRequestObject()->SetStringField(TEXT("phone"), EMailOrNumber);
504 | }
505 |
506 | Request->GetRequestObject()->SetStringField(TEXT("message"), this->GetLangText("SDK_SUBSCRIBE_GET_NOTIFIED"));
507 |
508 | Request->ProcessUrl(this->GetRestUrl().Append(TEXT("/authentication/subscribe")));
509 | }
510 |
511 | void UStomtAPI::OnSendEMailResponse(UStomtRestRequest * Request)
512 | {
513 | if (Request->GetResponseCode() != 200) return;
514 | if (!Request->GetResponseObject()->HasField(TEXT("data"))) return;
515 | if (!Request->GetResponseObject()->GetObjectField(TEXT("data"))->HasField(TEXT("success"))) return;
516 | if (!Request->GetResponseObject()->GetObjectField(TEXT("data"))->GetBoolField("success")) return;
517 |
518 | this->Config->SetSubscribed(true);
519 | this->Track->SetEventCategory("auth");
520 | this->Track->SetEventAction("subscribed");
521 | this->SendTrack(this->Track);
522 | }
523 |
524 | void UStomtAPI::SendLogoutRequest()
525 | {
526 | UStomtRestRequest* Request = this->SetupNewRequest(StomtEnumRequestVerb::DEL);
527 | Request->OnRequestComplete.AddDynamic(this, &UStomtAPI::UStomtAPI::OnSendLogoutResponse);
528 | Request->ProcessUrl(this->GetRestUrl().Append(TEXT("/authentication/session")));
529 |
530 | this->Config->SetAccessToken(TEXT(""));
531 | this->Config->SetLoggedIn(false);
532 | this->Config->SetSubscribed(false);
533 | }
534 |
535 | void UStomtAPI::OnSendLogoutResponse(UStomtRestRequest * Request)
536 | {
537 | if (Request->GetResponseCode() == 200)
538 | {
539 | if (Request->GetResponseObject()->HasField(TEXT("data")))
540 | {
541 | if (Request->GetResponseObject()->GetObjectField(TEXT("data"))->HasField(TEXT("success")))
542 | {
543 | if (Request->GetResponseObject()->GetObjectField(TEXT("data"))->GetBoolField("success"))
544 | {
545 | return; // logout was successful
546 | }
547 | }
548 | }
549 | }
550 |
551 | UE_LOG(StomtNetwork, Warning, TEXT("Logout failed"));
552 | }
553 |
554 | void UStomtAPI::SendTrack(UStomtTrack * NewTrack)
555 | {
556 | UStomtRestRequest* Request = this->SetupNewRequest(StomtEnumRequestVerb::POST);
557 |
558 | // Add target id
559 | NewTrack->SetTargetId(this->GetTargetId());
560 | UStomtRestJsonObject* JObjTrack = NewTrack->GetAsJsonObject();
561 |
562 | if (JObjTrack == NULL)
563 | {
564 | UE_LOG(StomtNetwork, Warning, TEXT("SendTrack: track was null"));
565 | return;
566 | }
567 |
568 | if (!JObjTrack->IsValidLowLevel())
569 | {
570 | UE_LOG(StomtNetwork, Warning, TEXT("SendTrack: track not valid"));
571 | return;
572 | }
573 |
574 | Request->SetRequestObject(JObjTrack);
575 | Request->ProcessUrl(this->GetRestUrl().Append(TEXT("/tracks")));
576 | }
577 |
578 |
579 | //////////////////////////////////////////////////////////////////////////
580 | // Other
581 |
582 | FString UStomtAPI::ReadLogFile(FString LogFileName)
583 | {
584 | FString ErrorLog;
585 |
586 | FString LogFilePath = FPaths::ProjectLogDir() + LogFileName;
587 | FString LogFileCopyPath = FPaths::ProjectLogDir() + LogFileName + TEXT("Copy.log");
588 | FString LogFileCopyName = LogFileName + TEXT("Copy.log");
589 |
590 | IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
591 | PlatformFile.BypassSecurity(true);
592 |
593 | // Copy LogFileData
594 | if (!PlatformFile.CopyFile(*LogFileCopyPath, *LogFilePath, EPlatformFileRead::AllowWrite, EPlatformFileWrite::AllowRead))
595 | {
596 | UE_LOG(StomtFileAccess, Warning, TEXT("LogFile Copy did not work FromFile: %s | ToFile %s"), *LogFilePath, *LogFileCopyPath);
597 | return TEXT("");
598 | }
599 |
600 | // Read LogFileCopy from Disk
601 | if (!this->ReadFile(ErrorLog, LogFileCopyName, FPaths::ProjectLogDir() ))
602 | {
603 | if (FPaths::FileExists(FPaths::ProjectLogDir() + LogFileCopyName))
604 | {
605 | UE_LOG(StomtFileAccess, Warning, TEXT("Could not read LogFile %s, but it exists"), *LogFileCopyName);
606 | }
607 | else
608 | {
609 | UE_LOG(StomtFileAccess, Warning, TEXT("Could not read LogFile %s, because it does not exist"), *LogFileCopyName);
610 | }
611 | }
612 |
613 | // Delete LogFileCopy
614 | if (!PlatformFile.DeleteFile(*LogFileCopyPath))
615 | {
616 | UE_LOG(StomtFileAccess, Warning, TEXT("Could not delete LogFileCopy %s"), *LogFileCopyPath);
617 | }
618 |
619 | return ErrorLog;
620 | }
621 |
622 | FString UStomtAPI::ReadScreenshotAsBase64()
623 | {
624 | FString ScreenDir = FPaths::ScreenShotDir();
625 | FString FilePath = ScreenDir + this->DefaultScreenshotName;
626 |
627 | UE_LOG(StomtLog, Log, TEXT("TakeScreenshot | FilePath: %s"), *FilePath);
628 | UE_LOG(StomtLog, Log, TEXT("Screenshot | AllocatedSize: %d"), this->ReadBinaryFile(FilePath).GetAllocatedSize());
629 |
630 | TArray File = this->ReadBinaryFile(FilePath);
631 |
632 | //Delete Screenshot
633 | FString AbsoluteFilePath = ScreenDir + this->DefaultScreenshotName;
634 | if (!FPlatformFileManager::Get().GetPlatformFile().DeleteFile(*AbsoluteFilePath))
635 | {
636 | UE_LOG(StomtFileAccess, Warning, TEXT("Could not delete old screenshot File (Could Not Find Screenshot File)") );
637 | }
638 |
639 | return FBase64::Encode(File);
640 | }
641 |
642 | void UStomtAPI::ConnectionTest()
643 | {
644 | this->RequestTargetByAppId();
645 | }
646 |
647 | UStomtRestJsonObject* UStomtAPI::LoadLanguageFile()
648 | {
649 | FString JsonString = this->LoadLanguageFileContent();
650 | UStomtRestJsonObject* JsonObject = UStomtRestJsonObject::ConstructJsonObject(this);
651 | if (JsonObject->DecodeJson(JsonString))
652 | {
653 | this->Languages = JsonObject;
654 | }
655 | else
656 | {
657 | UE_LOG(StomtInit, Error, TEXT("Could not decode Language File StomtPlugin(Sub)/Resources/languages.json"));
658 | }
659 |
660 | return JsonObject;
661 | }
662 |
663 | FString UStomtAPI::LoadLanguageFileContent()
664 | {
665 | TArray PluginFolders;
666 | PluginFolders.Add(FPaths::EnginePluginsDir() + "Marketplace/");
667 | PluginFolders.Add(FPaths::ProjectPluginsDir());
668 | PluginFolders.Add(FPaths::ProjectPluginsDir());
669 | PluginFolders.Add(FPaths::EnterprisePluginsDir());
670 |
671 | TArray PluginNames;
672 | PluginNames.Add("StomtPlugin/");
673 | PluginNames.Add("StomtPluginSub/");
674 | PluginNames.Add("stomt-unreal-plugin/");
675 |
676 | FString LocalFolder = "Resources/";
677 |
678 | FString FileName = "languages.json";
679 |
680 | FString WorkingPath = "";
681 |
682 | for (auto& StrFolder : PluginFolders)
683 | {
684 | for (auto& StrPluginName : PluginNames)
685 | {
686 | if (FPaths::FileExists(StrFolder + StrPluginName + LocalFolder + FileName))
687 | {
688 | WorkingPath = StrFolder + StrPluginName + LocalFolder;
689 | UE_LOG(StomtInit, Log, TEXT("Using language file in path: %s"), *WorkingPath);
690 | }
691 | }
692 | }
693 |
694 | FString JsonString = "";
695 |
696 | if( this->ReadFile(JsonString, FileName, WorkingPath) )
697 | {
698 | return JsonString;
699 | }
700 |
701 | if (WorkingPath.IsEmpty())
702 | {
703 | UE_LOG(StomtInit, Warning, TEXT("Language file not found"));
704 |
705 | JsonString = "{\"data\":{\"de\": {\"SDK_STOMT_WISH_BUBBLE\": \"Ich wünschte\",\"SDK_STOMT_LIKE_BUBBLE\": \"Ich mag\",\"SDK_STOMT_DEFAULT_TEXT_WISH\": \"würde\",\"SDK_STOMT_DEFAULT_TEXT_LIKE\": \"weil\",\"SDK_STOMT_PLACEHOLDER\": \"...bitte beende diesen Satz\",\"SDK_STOMT_ERROR_MORE_TEXT\": \"Bitte schreibe etwas mehr.\",\"SDK_STOMT_ERROR_LESS_TEXT\": \"Nutze nur {0} Zeichen.\", \"SDK_STOMT_SCREENSHOT\": \"Screenshot\",\"SDK_HEADER_TARGET_STOMTS\": \"STOMTS\",\"SDK_HEADER_YOUR_STOMTS\": \"DEINE\",\"SDK_SUBSCRIBE_GET_NOTIFIED\": \"Werde benachrichtigt, wenn jemand reagiert.\",\"SDK_SUBSCRIBE_TOGGLE_EMAIL\": \"E-Mail\",\"SDK_SUBSCRIBE_TOGGLE_PHONE\": \"SMS\",\"SDK_SUBSCRIBE_EMAIL_QUESTION\": \"Wie lautet deine E-Mail-Adresse?\",\"SDK_SUBSCRIBE_PHONE_QUESTION\": \"Wie lautet deine Telefonnummer?\",\"SDK_SUBSCRIBE_PHONE_PLACEHOLDER\" : \"+49 152 03959902\",\"SDK_SUBSCRIBE_EMAIL_PLACEHOLDER\" : \"deine@email.com\",\"SDK_SUBSCRIBE_DEFAULT_PLACEHOLDER\" : \"Wir senden dir keine Spam Nachrichten\",\"SDK_SUBSCRIBE_VALID_EMAIL\" : \"E-Mail-Adresse ist gültig, fantastisch!\",\"SDK_SUBSCRIBE_NO_VALID_EMAIL\" : \"Bitte gebe eine gültige Adresse ein.\",\"SDK_SUBSCRIBE_SKIP\": \"Überspringen\",\"SDK_SUCCESS_THANK_YOU\": \"DANKE!\",\"SDK_SUCCESS_FIND_ALL_STOMTS\": \"Super, finde mehr Wünsche auf\",\"SDK_SUCCESS_FIND_YOUR_STOMTS\": \"Finde deine stomts\",\"SDK_SUCCESS_CREATE_NEW_WISH\": \"Wünsch dir noch was\",\"SDK_NETWORK_NOT_CONNECTED\": \"Verbindung zu STOMT unterbrochen\",\"SDK_NETWORK_NO_INTERNET\": \"Keine Internetverbindung\",\"SDK_NETWORK_RECONNECT\": \"Wiederverbinden\",\"SDK_LOGIN_ACCOUNT_WRONG\": \"Account Name stimmt nicht.\",\"SDK_LOGIN_PASSWORD_WRONG\": \"Passwort stimmt nicht.\",\"SDK_LOGIN_PASSWORD\": \"Passwort\",\"SDK_LOGIN\": \"Login\",\"SDK_LOGIN_SIGNUP\": \"Anmelden\",\"SDK_LOGIN_LOGOUT\": \"Ausloggen\",\"SDK_LOGIN_FORGOT_PW\": \"Passwort vergessen?\",\"SDK_LOGIN_SUCCESS\": \"Du bist eingeloggt!\",\"SDK_LOGIN_WENT_WRONG\": \"Ups, da lief was schief.\",\"SDK_ADD_DETAILS\": \"Mehr Text\",\"SDK_TERMS_LOGS_OPT_IN\": \"Dürfen wir Log-Dateien mitsenden?\",\"SDK_TERMS_LOGS_OPT_IN_DIS\": \"Nein, bitte nicht.\",\"SDK_TERMS_LOGS_OPT_OUT\": \"Wir werden Log-Dateien anhängen.\",\"SDK_TERMS_LOGS_OPT_OUT_DIS\": \"Keine Log-Dateien anhängen.\"},\"en\": {\"SDK_STOMT_WISH_BUBBLE\": \"I wish\",\"SDK_STOMT_LIKE_BUBBLE\": \"I like\",\"SDK_STOMT_DEFAULT_TEXT_WISH\": \"would\",\"SDK_STOMT_DEFAULT_TEXT_LIKE\": \"because\",\"SDK_STOMT_PLACEHOLDER\": \"...please finish the sentence\",\"SDK_STOMT_ERROR_MORE_TEXT\": \"Please write a bit more.\",\"SDK_STOMT_ERROR_LESS_TEXT\": \"Use only {0} characters.\", \"SDK_STOMT_SCREENSHOT\": \"Screenshot\",\"SDK_HEADER_TARGET_STOMTS\": \"STOMTS\",\"SDK_HEADER_YOUR_STOMTS\": \"YOURS\",\"SDK_SUBSCRIBE_GET_NOTIFIED\": \"Get notified when someone reacts.\",\"SDK_SUBSCRIBE_TOGGLE_EMAIL\": \"E-Mail\",\"SDK_SUBSCRIBE_TOGGLE_PHONE\": \"SMS\",\"SDK_SUBSCRIBE_EMAIL_QUESTION\": \"What's your email address?\",\"SDK_SUBSCRIBE_PHONE_QUESTION\": \"What's your phone number?\",\"SDK_SUBSCRIBE_PHONE_PLACEHOLDER\" : \"+1-541-754-3010\",\"SDK_SUBSCRIBE_EMAIL_PLACEHOLDER\" : \"your@gmail.com\",\"SDK_SUBSCRIBE_DEFAULT_PLACEHOLDER\" : \"We won’t share your contact nor spam you.\",\"SDK_SUBSCRIBE_VALID_EMAIL\" : \"Email address is valid, fantastic!\",\"SDK_SUBSCRIBE_NO_VALID_EMAIL\" : \"Please type in a valid address.\",\"SDK_SUBSCRIBE_SKIP\": \"Skip\",\"SDK_SUCCESS_THANK_YOU\": \"THANK YOU!\",\"SDK_SUCCESS_FIND_ALL_STOMTS\": \"Amazing, find more wishes on\",\"SDK_SUCCESS_FIND_YOUR_STOMTS\": \"click to find your stomts here\",\"SDK_SUCCESS_CREATE_NEW_WISH\": \"Create another wish\",\"SDK_NETWORK_NOT_CONNECTED\": \"Could not connect to STOMT\",\"SDK_NETWORK_NO_INTERNET\": \"No internet connection\",\"SDK_NETWORK_RECONNECT\": \"Reconnect\",\"SDK_LOGIN_ACCOUNT_WRONG\": \"Account was incorrect.\",\"SDK_LOGIN_PASSWORD_WRONG\": \"Password was incorrect.\",\"SDK_LOGIN_PASSWORD\": \"Password\",\"SDK_LOGIN\": \"Login\",\"SDK_LOGIN_SIGNUP\": \"Signup\",\"SDK_LOGIN_LOGOUT\": \"Logout\",\"SDK_LOGIN_FORGOT_PW\": \"Forgot password?\",\"SDK_LOGIN_SUCCESS\": \"You're now logged in!\",\"SDK_LOGIN_WENT_WRONG\": \"Ups something went wrong.\",\"SDK_ADD_DETAILS\": \"More Text\",\"SDK_TERMS_LOGS_OPT_IN\": \"May we attach log files?\",\"SDK_TERMS_LOGS_OPT_IN_DIS\": \"No, please don't.\",\"SDK_TERMS_LOGS_OPT_OUT\": \"We will attach log files to your stomt.\",\"SDK_TERMS_LOGS_OPT_OUT_DIS\": \"Do not attach log files.\"}}}";
706 | return JsonString;
707 | }
708 |
709 | return JsonString;
710 | }
711 |
712 | FString UStomtAPI::GetLangText(FString Text)
713 | {
714 | if (this->CurrentLanguage.IsEmpty())
715 | {
716 | this->CurrentLanguage = "en";
717 | }
718 |
719 | if (this->Languages != NULL)
720 | {
721 | if (!this->Languages->HasField("data"))
722 | {
723 | return "";
724 | }
725 |
726 | if (this->Languages->GetObjectField("data") != NULL)
727 | {
728 | if (!this->Languages->GetObjectField("data")->HasField(this->CurrentLanguage))
729 | {
730 | UE_LOG(StomtNetwork, Warning, TEXT("Language %s not supported (does not exist in language file) falling back to english."), *this->CurrentLanguage);
731 | this->CurrentLanguage = "en";
732 | }
733 |
734 | if (!this->Languages->GetObjectField("data")->GetObjectField(this->CurrentLanguage)->HasField(Text))
735 | {
736 | UE_LOG(StomtNetwork, Warning, TEXT("Translation for '%s' not found in language: '%s'."), *Text, *this->CurrentLanguage);
737 | return "No Transl.";
738 | }
739 |
740 | return this->Languages->GetObjectField("data")->GetObjectField(this->CurrentLanguage)->GetStringField(Text);
741 | }
742 | }
743 |
744 | return FString();
745 | }
746 |
747 | bool UStomtAPI::IsEmailCorrect(FString Email)
748 | {
749 | const FRegexPattern Pattern(TEXT("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"));
750 | FRegexMatcher matcher(Pattern, Email);
751 |
752 | return matcher.FindNext();
753 | }
754 |
755 | bool UStomtAPI::DoesScreenshotFileExist()
756 | {
757 | return FPaths::FileExists(FPaths::ScreenShotDir() + this->DefaultScreenshotName);
758 | }
759 |
760 | void UStomtAPI::UseScreenshotUpload(bool bUseUpload)
761 | {
762 | this->bUseImageUpload = bUseUpload;
763 | }
764 |
765 | void UStomtAPI::AddCustomKeyValuePair(FString Key, FString Value)
766 | {
767 | TArray Pair = TArray();
768 | Pair.Add(Key);
769 | Pair.Add(Value);
770 |
771 | CustomKeyValuePairs.Add(Pair);
772 | }
773 |
774 | void UStomtAPI::HandleOfflineStomts()
775 | {
776 | if (this->IsConnected())
777 | {
778 | UE_LOG(StomtNetwork, Log, TEXT("Stomt API is connected."));
779 | this->SendOfflineStomts();
780 | }
781 | else
782 | {
783 | this->Config->AddStomt(this->StomtToSend);
784 | }
785 | }
786 |
787 | void UStomtAPI::SendOfflineStomts()
788 | {
789 | TArray Stomts = this->Config->GetStomts();
790 | if (Stomts.Num() > 0)
791 | {
792 | UE_LOG(StomtNetwork, Log, TEXT("Start sending offline stomts: %d"), Stomts.Num());
793 | for (UStomt* OneStomt : Stomts)
794 | {
795 | UE_LOG(StomtNetwork, Log, TEXT("Sending Offline Stomt"));
796 | this->SendStomt(OneStomt);
797 | }
798 |
799 | this->Config->ClearStomts();
800 | }
801 | }
802 |
803 | bool UStomtAPI::WriteFile(FString TextToSave, FString FileName, FString SaveDirectory, bool bAllowOverwriting)
804 | {
805 | IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
806 |
807 | // CreateDirectoryTree returns true if the destination
808 | // directory existed prior to call or has been created
809 | // during the call.
810 | if (PlatformFile.CreateDirectoryTree(*SaveDirectory))
811 | {
812 | // Get absolute file path
813 | FString AbsoluteFilePath = SaveDirectory + "/" + FileName;
814 |
815 | // Allow overwriting or file doesn't already exist
816 | if (bAllowOverwriting || !FPaths::FileExists(*AbsoluteFilePath))
817 | {
818 | //Use " FFileHelper::EEncodingOptions::AutoDetect, &IFileManager::Get(), EFileWrite::FILEWRITE_Append);" for append
819 | return FFileHelper::SaveStringToFile(TextToSave, *AbsoluteFilePath);
820 | }
821 | else
822 | {
823 | return false;
824 | }
825 | }
826 | else
827 | {
828 | return false;
829 | }
830 | }
831 |
832 | bool UStomtAPI::ReadFile(FString& Result, FString FileName, FString SaveDirectory)
833 | {
834 | FString Path = SaveDirectory + FileName;
835 |
836 | if (!FPaths::FileExists(Path))
837 | {
838 | UE_LOG(StomtFileAccess, Warning, TEXT("File with this path does not exist: %s "), *Path);
839 |
840 | return false;
841 | }
842 |
843 | return FFileHelper::LoadFileToString( Result, *Path);
844 | }
845 |
846 | TArray UStomtAPI::ReadBinaryFile(FString FilePath)
847 | {
848 | TArray BufferArray;
849 | FFileHelper::LoadFileToArray(BufferArray, *FilePath);
850 |
851 | return BufferArray;
852 | }
853 |
--------------------------------------------------------------------------------
/Source/StomtPlugin/Private/StomtConfig.cpp:
--------------------------------------------------------------------------------
1 | // Copyright 2018 STOMT GmbH. All Rights Reserved.
2 | #pragma once
3 |
4 | #include "StomtConfig.h"
5 | #include "StomtPluginPrivatePCH.h"
6 | #include "StomtJsonObject.h"
7 |
8 |
9 | #include "Runtime/Core/Public/Misc/FileHelper.h"
10 | #include "Runtime/Core/Public/Misc/Paths.h"
11 | #include "Runtime/Core/Public/GenericPlatform/GenericPlatformFile.h"
12 | #include "Runtime/Core/Public/Misc/App.h"
13 |
14 | UStomtConfig* UStomtConfig::ConstructStomtConfig()
15 | {
16 | UStomtConfig* Config = NewObject();
17 |
18 | Config->ConfigFolder = FPaths::EngineUserDir() + FString(TEXT("Saved/Config/stomt/"));
19 | UE_LOG(StomtInit, Log, TEXT("Config-Folder: %s"), *Config->ConfigFolder);
20 |
21 | Config->ConfigName = FString(TEXT("stomt.conf.json"));
22 | Config->AccessToken = FString(TEXT(""));
23 | Config->LoggedInFieldName = FString(TEXT("loggedin"));
24 | Config->SubscribedFieldName = FString(TEXT("email"));
25 | Config->AccessTokenFieldName = FString(TEXT("accesstoken"));
26 | Config->StomtsFieldName = FString(TEXT("stomts"));
27 | Config->LogUploadFieldName = FString(TEXT("acceptLogUpload"));
28 | Config->ScreenshotUploadFieldName = FString(TEXT("acceptScreenshotUpload"));
29 |
30 | Config->Load();
31 |
32 | return Config;
33 | }
34 |
35 | UStomtConfig::UStomtConfig()
36 | {
37 | }
38 |
39 | UStomtConfig::~UStomtConfig()
40 | {
41 | }
42 |
43 | void UStomtConfig::Load()
44 | {
45 | // Use this if you experience crashes at bake process.
46 | /* #if UE_EDITOR
47 | if (!IsRunningGame())
48 | {
49 | return;
50 | }
51 | #endif
52 | */
53 |
54 | if (FPaths::FileExists(this->ConfigFolder + this->ConfigName))
55 | {
56 | UStomtRestJsonObject* ConfigJsonObj = ReadStomtConfAsJson();
57 |
58 | if (ConfigJsonObj->HasField(this->AccessTokenFieldName))
59 | {
60 | this->AccessToken = ConfigJsonObj->GetStringField(this->AccessTokenFieldName);
61 | UE_LOG(StomtInit, Log, TEXT("AccessToken: %s"), *this->AccessToken);
62 | }
63 |
64 | if (ConfigJsonObj->HasField(this->SubscribedFieldName))
65 | {
66 | this->bSubscribed = ConfigJsonObj->GetBoolField(this->SubscribedFieldName);
67 | UE_LOG(StomtInit, Log, TEXT("Subscribed: %s"), this->bSubscribed ? TEXT("true") : TEXT("false"));
68 | }
69 | else
70 | {
71 | this->bSubscribed = false;
72 | }
73 |
74 | if (ConfigJsonObj->HasField(this->LoggedInFieldName))
75 | {
76 | this->bLoggedIn = ConfigJsonObj->GetBoolField(this->LoggedInFieldName);
77 | UE_LOG(StomtInit, Log, TEXT("LoggedIn: %s"), this->bLoggedIn ? TEXT("true") : TEXT("false") );
78 | }
79 | else
80 | {
81 | this->bLoggedIn = false;
82 | }
83 |
84 | if (ConfigJsonObj->HasField(this->LogUploadFieldName))
85 | {
86 | this->bAcceptLogUpload = ConfigJsonObj->GetBoolField(this->LogUploadFieldName);
87 | UE_LOG(StomtInit, Log, TEXT("Accept Log Upload: %s"), this->bAcceptLogUpload ? TEXT("true") : TEXT("false"));
88 | }
89 | else
90 | {
91 | this->bAcceptLogUpload = false;
92 | }
93 |
94 | if (ConfigJsonObj->HasField(this->ScreenshotUploadFieldName))
95 | {
96 | this->bAcceptScreenshotUpload = ConfigJsonObj->GetBoolField(this->ScreenshotUploadFieldName);
97 | UE_LOG(StomtInit, Log, TEXT("Accept Screenshot Upload: %s"), this->bAcceptScreenshotUpload ? TEXT("true") : TEXT("false"));
98 | }
99 | else
100 | {
101 | this->bAcceptScreenshotUpload = false;
102 | }
103 |
104 | if (ConfigJsonObj->HasField(this->StomtsFieldName))
105 | {
106 | this->Stomts = ConfigJsonObj->GetArrayField(this->StomtsFieldName);
107 | UE_LOG(StomtInit, Log, TEXT("Saved Offline Stomts: %d"), this->Stomts.Num());
108 | }
109 | else
110 | {
111 | UE_LOG(StomtInit, Log, TEXT("Saved Offline Stomts: 0"));
112 | }
113 |
114 | OnConfigUpdated.Broadcast(this);
115 | }
116 | else
117 | {
118 | // Force to create config file
119 | this->bSubscribed = true;
120 | this->bLoggedIn = true;
121 | this->SetSubscribed(false);
122 | this->SetLoggedIn(false);
123 |
124 | OnConfigUpdated.Broadcast(this);
125 | }
126 | }
127 |
128 | void UStomtConfig::Delete()
129 | {
130 | this->DeleteStomtConf();
131 | this->Load();
132 | }
133 |
134 | FString UStomtConfig::GetAccessToken()
135 | {
136 | if (this->AccessToken.IsEmpty())
137 | {
138 | this->AccessToken = this->ReadAccessToken();
139 | }
140 |
141 | return this->AccessToken;
142 | }
143 |
144 | void UStomtConfig::SetAccessToken(FString NewAccessToken)
145 | {
146 | if (this->AccessToken.Equals(NewAccessToken)) return;
147 |
148 | this->AccessToken = NewAccessToken;
149 |
150 | this->SaveAccessToken(this->AccessToken);
151 |
152 | OnConfigUpdated.Broadcast(this);
153 | }
154 |
155 | bool UStomtConfig::GetSubscribed()
156 | {
157 | return this->bSubscribed;
158 | }
159 |
160 | void UStomtConfig::SetSubscribed(bool bNewSubscribed)
161 | {
162 | if (this->bSubscribed == bNewSubscribed) return;
163 |
164 | this->bSubscribed = bNewSubscribed;
165 |
166 | this->SaveFlag(this->SubscribedFieldName, this->bSubscribed);
167 |
168 | OnConfigUpdated.Broadcast(this);
169 | }
170 |
171 | bool UStomtConfig::GetLoggedIn()
172 | {
173 | return this->bLoggedIn;
174 | }
175 |
176 | void UStomtConfig::SetLoggedIn(bool bNewLoggedIn)
177 | {
178 | if (this->bLoggedIn == bNewLoggedIn) return;
179 |
180 | this->bLoggedIn = bNewLoggedIn;
181 |
182 | this->SaveFlag(this->LoggedInFieldName, this->bLoggedIn);
183 |
184 | OnConfigUpdated.Broadcast(this);
185 | }
186 |
187 | bool UStomtConfig::GetAcceptScreenshotUpload()
188 | {
189 | return this->bAcceptScreenshotUpload;
190 | }
191 |
192 | void UStomtConfig::SetAcceptScreenshotUpload(bool bNewAcceptScreenshotUpload)
193 | {
194 | if (this->bAcceptScreenshotUpload == bNewAcceptScreenshotUpload) return;
195 |
196 | this->bAcceptScreenshotUpload = bNewAcceptScreenshotUpload;
197 |
198 | this->SaveFlag(this->ScreenshotUploadFieldName, this->bAcceptScreenshotUpload);
199 |
200 | OnConfigUpdated.Broadcast(this);
201 | }
202 |
203 | bool UStomtConfig::GetAcceptLogUpload()
204 | {
205 | return this->bAcceptLogUpload;
206 | }
207 |
208 | void UStomtConfig::SetAcceptLogUpload(bool bNewAcceptLogUpload)
209 | {
210 | if (this->bAcceptLogUpload == bNewAcceptLogUpload) return;
211 |
212 | this->bAcceptLogUpload = bNewAcceptLogUpload;
213 |
214 | this->SaveFlag(this->LogUploadFieldName, this->bAcceptLogUpload);
215 |
216 | OnConfigUpdated.Broadcast(this);
217 | }
218 |
219 | TArray UStomtConfig::GetStomtsAsJson()
220 | {
221 | UStomtRestJsonObject* JsonObj = ReadStomtConfAsJson();
222 |
223 | if (JsonObj->HasField(this->StomtsFieldName))
224 | {
225 | return JsonObj->GetArrayField(this->StomtsFieldName);
226 | }
227 | else
228 | {
229 | return TArray();
230 | }
231 | }
232 |
233 | TArray UStomtConfig::GetStomts()
234 | {
235 | TArray StomtObjects;
236 | UStomtRestJsonObject* JsonObj = ReadStomtConfAsJson();
237 |
238 | if (JsonObj->HasField(this->StomtsFieldName))
239 | {
240 | for (UStomtRestJsonObject* JObjStomt : JsonObj->GetObjectArrayField(this->StomtsFieldName))
241 | {
242 | UStomt* StomtObject = UStomt::ConstructStomt(
243 | JObjStomt->GetStringField("target_id"),
244 | JObjStomt->GetBoolField("positive"),
245 | JObjStomt->GetStringField("text"),
246 | JObjStomt->GetStringField("details")
247 | );
248 |
249 | StomtObjects.Add(StomtObject);
250 | }
251 | }
252 | else
253 | {
254 | return TArray();
255 | }
256 |
257 | return StomtObjects;
258 | }
259 |
260 | bool UStomtConfig::AddStomt(UStomt* NewStomt)
261 | {
262 | return SaveStomtToConf(*NewStomt);
263 | }
264 |
265 | bool UStomtConfig::SaveAccessToken(FString NewAccessToken)
266 | {
267 | return SaveValueToStomtConf(this->AccessTokenFieldName, NewAccessToken);
268 | }
269 |
270 | bool UStomtConfig::SaveValueToStomtConf(FString FieldName, FString FieldValue)
271 | {
272 | UStomtRestJsonObject* JsonObj = ReadStomtConfAsJson();
273 |
274 | if (JsonObj->HasField(FieldName))
275 | {
276 | if (JsonObj->GetStringField(FieldName).Equals(FieldValue))
277 | {
278 | return false;
279 | }
280 |
281 | JsonObj->RemoveField(FieldName);
282 | }
283 |
284 | JsonObj->SetStringField(FieldName, FieldValue);
285 |
286 | return this->WriteFile(JsonObj->EncodeJson(), this->ConfigName, this->ConfigFolder, true);
287 | }
288 |
289 | bool UStomtConfig::SaveStomtToConf(UStomt& NewStomt)
290 | {
291 | UStomtRestJsonObject* JsonObj = ReadStomtConfAsJson();
292 |
293 | UStomtRestJsonObject* JObjStomt = UStomtRestJsonObject::ConstructJsonObject(this);
294 | TArray Labels = TArray();
295 |
296 | for (int i = 0; i != NewStomt.GetLabels().Num(); ++i)
297 | {
298 | if (!NewStomt.GetLabels()[i]->GetName().IsEmpty())
299 | {
300 | Labels.Add(UStomtJsonValue::ConstructJsonValueString(this, NewStomt.GetLabels()[i]->GetName()));
301 | }
302 | }
303 |
304 | JObjStomt->SetField(TEXT("target_id"), UStomtJsonValue::ConstructJsonValueString(this, NewStomt.GetTargetId()));
305 | JObjStomt->SetField(TEXT("positive"), UStomtJsonValue::ConstructJsonValueBool(this, NewStomt.GetPositive()));
306 | JObjStomt->SetField(TEXT("text"), UStomtJsonValue::ConstructJsonValueString(this, NewStomt.GetText()));
307 | JObjStomt->SetField(TEXT("anonym"), UStomtJsonValue::ConstructJsonValueBool(this, NewStomt.GetAnonym()));
308 | JObjStomt->SetArrayField(TEXT("labels"), Labels);
309 |
310 | if (!JsonObj->HasField(StomtsFieldName))
311 | {
312 | TArray JObjArray1;
313 | JObjArray1.Add(JObjStomt);
314 | JsonObj->SetObjectArrayField(StomtsFieldName, JObjArray1);
315 |
316 | UE_LOG(StomtNetwork, Log, TEXT("Add Offline Stomt: To new field"));
317 | }
318 | else
319 | {
320 | TArray JObjArray2;
321 | JObjArray2 = JsonObj->GetObjectArrayField(StomtsFieldName);
322 | JObjArray2.Add(JObjStomt);
323 | JsonObj->SetObjectArrayField(StomtsFieldName, JObjArray2);
324 | UE_LOG(StomtNetwork, Log, TEXT("Add Offline Stomt: To existing field"));
325 | }
326 |
327 | UE_LOG(StomtNetwork, Log, TEXT("Add offline stomt: %s"), *JsonObj->EncodeJson());
328 |
329 | return this->WriteFile(JsonObj->EncodeJson(), this->ConfigName, this->ConfigFolder, true);
330 | }
331 |
332 | bool UStomtConfig::ClearStomts()
333 | {
334 | UStomtRestJsonObject* JsonObj = ReadStomtConfAsJson();
335 |
336 | if (JsonObj->HasField(StomtsFieldName))
337 | {
338 | UE_LOG(StomtNetwork, Log, TEXT("Clear offline stomts"));
339 | JsonObj->GetArrayField(StomtsFieldName).Empty();
340 | JsonObj->RemoveField(StomtsFieldName);
341 | }
342 | else
343 | {
344 | return true;
345 | }
346 |
347 | return this->WriteFile(JsonObj->EncodeJson(), this->ConfigName, this->ConfigFolder, true);
348 | }
349 |
350 | bool UStomtConfig::SaveFlag(FString FlagName, bool bFlagState)
351 | {
352 | return SaveValueToStomtConf(FlagName, bFlagState ? TEXT("true") : TEXT("false"));
353 | }
354 |
355 | FString UStomtConfig::ReadStomtConf(FString FieldName)
356 | {
357 | FString Result;
358 |
359 | if (this->ReadFile(Result, this->ConfigName, this->ConfigFolder))
360 | {
361 | UStomtRestJsonObject* JsonObj = UStomtRestJsonObject::ConstructJsonObject(this);
362 | JsonObj->DecodeJson(Result);
363 | this->AccessToken = JsonObj->GetField(FieldName)->AsString();
364 | }
365 |
366 | return Result;
367 | }
368 |
369 | bool UStomtConfig::ReadFlag(FString FlagName)
370 | {
371 | FString Result;
372 | bool bFlagState = false;
373 |
374 | if (this->ReadFile(Result, this->ConfigName, this->ConfigFolder))
375 | {
376 | UStomtRestJsonObject* JsonObj = UStomtRestJsonObject::ConstructJsonObject(this);
377 | JsonObj->DecodeJson(Result);
378 | bFlagState = JsonObj->GetField(FlagName)->AsBool();
379 | }
380 |
381 | return bFlagState;
382 | }
383 |
384 | UStomtRestJsonObject* UStomtConfig::ReadStomtConfAsJson()
385 | {
386 | FString Result;
387 | UStomtRestJsonObject* JsonObj = UStomtRestJsonObject::ConstructJsonObject(this);
388 |
389 | if (this->ReadFile(Result, this->ConfigName, this->ConfigFolder))
390 | {
391 | JsonObj->DecodeJson(Result);
392 | }
393 |
394 | return JsonObj;
395 | }
396 |
397 | FString UStomtConfig::ReadAccessToken()
398 | {
399 | UStomtRestJsonObject* StomtConfigJson = this->ReadStomtConfAsJson();
400 |
401 | if (StomtConfigJson->HasField(this->AccessTokenFieldName))
402 | {
403 | return StomtConfigJson->GetStringField(this->AccessTokenFieldName);
404 | }
405 |
406 | return FString(TEXT(""));
407 | }
408 |
409 | bool UStomtConfig::WriteStomtConfAsJson(UStomtRestJsonObject * StomtConf)
410 | {
411 | return this->WriteFile(StomtConf->EncodeJson(), this->ConfigName, this->ConfigFolder, true);
412 | }
413 |
414 | void UStomtConfig::DeleteStomtConf()
415 | {
416 | FString File = this->ConfigFolder + this->ConfigName;
417 | if (!FPlatformFileManager::Get().GetPlatformFile().DeleteFile(*File))
418 | {
419 | UE_LOG(StomtFileAccess, Warning, TEXT("Could not delete stomt.conf.json: %s"), *File);
420 | }
421 | else
422 | {
423 | UE_LOG(StomtFileAccess, Warning, TEXT("Deleted stomt.conf.json because of wrong access token Path: %s"), *File);
424 | }
425 | }
426 |
427 | FString UStomtConfig::ReadLogFile(FString LogFileName)
428 | {
429 | FString ErrorLog;
430 |
431 | FString LogFilePath = FPaths::ProjectLogDir() + LogFileName;
432 | FString LogFileCopyPath = FPaths::ProjectLogDir() + LogFileName + TEXT("Copy.log");
433 | FString LogFileCopyName = LogFileName + TEXT("Copy.log");
434 |
435 | IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
436 | PlatformFile.BypassSecurity(true);
437 |
438 | // Copy LogFileData
439 | if (!PlatformFile.CopyFile(*LogFileCopyPath, *LogFilePath, EPlatformFileRead::AllowWrite, EPlatformFileWrite::AllowRead))
440 | {
441 | UE_LOG(StomtFileAccess, Warning, TEXT("LogFile Copy did not work FromFile: %s | ToFile %s"), *LogFilePath, *LogFileCopyPath);
442 | }
443 |
444 | // Read LogFileCopy from Disk
445 | if (!this->ReadFile(ErrorLog, LogFileCopyName, FPaths::ProjectLogDir()))
446 | {
447 | if (FPaths::FileExists(FPaths::ProjectLogDir() + LogFileCopyName))
448 | {
449 | UE_LOG(StomtFileAccess, Warning, TEXT("Could not read LogFile %s, but it exists"), *LogFileCopyName);
450 | }
451 | else
452 | {
453 | UE_LOG(StomtFileAccess, Warning, TEXT("Could not read LogFile %s, because it does not exist"), *LogFileCopyName);
454 | }
455 | }
456 |
457 | // Delete LogFileCopy
458 | if (!PlatformFile.DeleteFile(*LogFileCopyPath))
459 | {
460 | UE_LOG(StomtFileAccess, Warning, TEXT("Could not delete LogFileCopy %s"), *LogFileCopyPath);
461 | }
462 |
463 | return ErrorLog;
464 | }
465 |
466 | bool UStomtConfig::WriteFile(FString TextToSave, FString FileName, FString SaveDirectory, bool bAllowOverwriting)
467 | {
468 | IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
469 |
470 | // CreateDirectoryTree returns true if the destination
471 | // directory existed prior to call or has been created
472 | // during the call.
473 | if (PlatformFile.CreateDirectoryTree(*SaveDirectory))
474 | {
475 | // Get absolute file path
476 | FString AbsoluteFilePath = SaveDirectory + "/" + FileName;
477 |
478 | // Allow overwriting or file doesn't already exist
479 | if (bAllowOverwriting || !FPaths::FileExists(*AbsoluteFilePath))
480 | {
481 | // Use " FFileHelper::EEncodingOptions::AutoDetect, &IFileManager::Get(), EFileWrite::FILEWRITE_Append);" for append
482 | return FFileHelper::SaveStringToFile(TextToSave, *AbsoluteFilePath);
483 | }
484 | }
485 |
486 | return false;
487 | }
488 |
489 | bool UStomtConfig::ReadFile(FString& Result, FString FileName, FString SaveDirectory)
490 | {
491 | FString Path = SaveDirectory + FileName;
492 |
493 | if (!FPaths::FileExists(Path))
494 | {
495 | UE_LOG(StomtFileAccess, Warning, TEXT("File with this path does not exist: %s "), *Path);
496 | }
497 |
498 | return FFileHelper::LoadFileToString(Result, *Path);
499 | }
500 |
--------------------------------------------------------------------------------
/Source/StomtPlugin/Private/StomtJsonObject.cpp:
--------------------------------------------------------------------------------
1 | // Copyright 2018 STOMT GmbH. All Rights Reserved.
2 | #pragma once
3 |
4 | #include "StomtJsonObject.h"
5 | #include "StomtPluginPrivatePCH.h"
6 |
7 | typedef TJsonWriterFactory< TCHAR, TCondensedJsonPrintPolicy > FCondensedJsonStringWriterFactory;
8 | typedef TJsonWriter< TCHAR, TCondensedJsonPrintPolicy > FCondensedJsonStringWriter;
9 |
10 | UStomtRestJsonObject::UStomtRestJsonObject()
11 | {
12 | Reset();
13 | }
14 |
15 | UStomtRestJsonObject* UStomtRestJsonObject::ConstructJsonObject(UObject* WorldContextObject)
16 | {
17 | return NewObject();
18 | }
19 |
20 | void UStomtRestJsonObject::Reset()
21 | {
22 | if (JsonObj.IsValid())
23 | {
24 | JsonObj.Reset();
25 | }
26 |
27 | JsonObj = MakeShareable(new FJsonObject());
28 | }
29 |
30 | TSharedPtr& UStomtRestJsonObject::GetRootObject()
31 | {
32 | return JsonObj;
33 | }
34 |
35 | void UStomtRestJsonObject::SetRootObject(TSharedPtr& JsonObject)
36 | {
37 | JsonObj = JsonObject;
38 | }
39 |
40 |
41 | ////////////////////////////////////////////////////////////////////////////
42 | //// Serialization
43 |
44 | FString UStomtRestJsonObject::EncodeJson() const
45 | {
46 | if (!JsonObj.IsValid())
47 | {
48 | return TEXT("");
49 | }
50 |
51 | FString OutputString;
52 | TSharedRef< FCondensedJsonStringWriter > Writer = FCondensedJsonStringWriterFactory::Create(&OutputString);
53 | FJsonSerializer::Serialize(JsonObj.ToSharedRef(), Writer);
54 |
55 | return OutputString;
56 | }
57 |
58 | FString UStomtRestJsonObject::EncodeJsonToSingleString() const
59 | {
60 | FString OutputString = EncodeJson();
61 |
62 | // Remove line terminators
63 | OutputString.Replace(LINE_TERMINATOR, TEXT(""));
64 |
65 | // Remove tabs
66 | OutputString.Replace(LINE_TERMINATOR, TEXT("\t"));
67 |
68 | return OutputString;
69 | }
70 |
71 | bool UStomtRestJsonObject::DecodeJson(const FString& JsonString)
72 | {
73 | TSharedRef< TJsonReader<> > Reader = TJsonReaderFactory<>::Create(*JsonString);
74 | if (FJsonSerializer::Deserialize(Reader, JsonObj) && JsonObj.IsValid())
75 | {
76 | return true;
77 | }
78 |
79 | // If we've failed to deserialize the string, we should clear our internal data
80 | Reset();
81 |
82 | UE_LOG(StomtLog, Error, TEXT("Json decoding failed for: %s"), *JsonString);
83 |
84 | return false;
85 | }
86 |
87 |
88 | ////////////////////////////////////////////////////////////////////////////
89 | //// FJsonObject API
90 | //
91 | TArray UStomtRestJsonObject::GetFieldNames()
92 | {
93 | TArray Result;
94 |
95 | if (!JsonObj.IsValid())
96 | {
97 | return Result;
98 | }
99 |
100 | JsonObj->Values.GetKeys(Result);
101 |
102 | return Result;
103 | }
104 |
105 | bool UStomtRestJsonObject::HasField(const FString& FieldName) const
106 | {
107 | if (!JsonObj.IsValid())
108 | {
109 | return false;
110 | }
111 |
112 | return JsonObj->HasField(FieldName);
113 | }
114 |
115 | void UStomtRestJsonObject::RemoveField(const FString& FieldName)
116 | {
117 | if (!JsonObj.IsValid())
118 | {
119 | return;
120 | }
121 |
122 | JsonObj->RemoveField(FieldName);
123 | }
124 |
125 | UStomtJsonValue* UStomtRestJsonObject::GetField(const FString& FieldName) const
126 | {
127 | if (!JsonObj.IsValid())
128 | {
129 | return NULL;
130 | }
131 |
132 | TSharedPtr NewVal = JsonObj->TryGetField(FieldName);
133 |
134 | UStomtJsonValue* NewValue = NewObject();
135 | NewValue->SetRootValue(NewVal);
136 |
137 | return NewValue;
138 | }
139 |
140 | void UStomtRestJsonObject::SetField(const FString& FieldName, UStomtJsonValue* JsonValue)
141 | {
142 | if (!JsonObj.IsValid())
143 | {
144 | return;
145 | }
146 |
147 | JsonObj->SetField(FieldName, JsonValue->GetRootValue());
148 | }
149 |
150 |
151 | ////////////////////////////////////////////////////////////////////////////
152 | //// FJsonObject API Helpers (easy to use with simple Json objects)
153 |
154 | float UStomtRestJsonObject::GetNumberField(const FString& FieldName) const
155 | {
156 | if (!JsonObj.IsValid())
157 | {
158 | return 0.0f;
159 | }
160 |
161 | return JsonObj->GetNumberField(FieldName);
162 | }
163 |
164 | void UStomtRestJsonObject::SetNumberField(const FString& FieldName, float Number)
165 | {
166 | if (!JsonObj.IsValid())
167 | {
168 | return;
169 | }
170 |
171 | JsonObj->SetNumberField(FieldName, Number);
172 | }
173 |
174 | FString UStomtRestJsonObject::GetStringField(const FString& FieldName) const
175 | {
176 | if (!JsonObj.IsValid())
177 | {
178 | return TEXT("");
179 | }
180 |
181 | return JsonObj->GetStringField(FieldName);
182 | }
183 |
184 | void UStomtRestJsonObject::SetStringField(const FString& FieldName, const FString& StringValue)
185 | {
186 | if (!JsonObj.IsValid())
187 | {
188 | return;
189 | }
190 |
191 | JsonObj->SetStringField(FieldName, StringValue);
192 | }
193 |
194 | bool UStomtRestJsonObject::GetBoolField(const FString& FieldName) const
195 | {
196 | if (!JsonObj.IsValid())
197 | {
198 | return false;
199 | }
200 |
201 | return JsonObj->GetBoolField(FieldName);
202 | }
203 |
204 | void UStomtRestJsonObject::SetBoolField(const FString& FieldName, bool InValue)
205 | {
206 | if (!JsonObj.IsValid())
207 | {
208 | return;
209 | }
210 |
211 | JsonObj->SetBoolField(FieldName, InValue);
212 | }
213 |
214 | TArray UStomtRestJsonObject::GetArrayField(const FString& FieldName)
215 | {
216 | TArray OutArray;
217 | if (!JsonObj.IsValid())
218 | {
219 | return OutArray;
220 | }
221 |
222 |
223 | TArray< TSharedPtr > ValArray = JsonObj->GetArrayField(FieldName);
224 | for (auto Value : ValArray)
225 | {
226 | UStomtJsonValue* NewValue = NewObject();
227 | NewValue->SetRootValue(Value);
228 |
229 | OutArray.Add(NewValue);
230 | }
231 |
232 | return OutArray;
233 | }
234 |
235 | void UStomtRestJsonObject::SetArrayField(const FString& FieldName, const TArray& InArray)
236 | {
237 | if (!JsonObj.IsValid())
238 | {
239 | return;
240 | }
241 |
242 | TArray< TSharedPtr > ValArray;
243 |
244 | // Process input array and COPY original values
245 | for (auto InVal : InArray)
246 | {
247 | TSharedPtr JsonVal = InVal->GetRootValue();
248 |
249 | switch (InVal->GetType())
250 | {
251 | case StomtEnumJson::None:
252 | break;
253 |
254 | case StomtEnumJson::Null:
255 | ValArray.Add(MakeShareable(new FJsonValueNull()));
256 | break;
257 |
258 | case StomtEnumJson::String:
259 | ValArray.Add(MakeShareable(new FJsonValueString(JsonVal->AsString())));
260 | break;
261 |
262 | case StomtEnumJson::Number:
263 | ValArray.Add(MakeShareable(new FJsonValueNumber(JsonVal->AsNumber())));
264 | break;
265 |
266 | case StomtEnumJson::Boolean:
267 | ValArray.Add(MakeShareable(new FJsonValueBoolean(JsonVal->AsBool())));
268 | break;
269 |
270 | case StomtEnumJson::Array:
271 | ValArray.Add(MakeShareable(new FJsonValueArray(JsonVal->AsArray())));
272 | break;
273 |
274 | case StomtEnumJson::Object:
275 | ValArray.Add(MakeShareable(new FJsonValueObject(JsonVal->AsObject())));
276 | break;
277 |
278 | default:
279 | break;
280 | }
281 | }
282 |
283 | JsonObj->SetArrayField(FieldName, ValArray);
284 | }
285 |
286 | void UStomtRestJsonObject::MergeJsonObject(UStomtRestJsonObject* InJsonObject, bool Overwrite)
287 | {
288 | TArray Keys = InJsonObject->GetFieldNames();
289 |
290 | for (auto Key : Keys)
291 | {
292 | if (Overwrite == false && HasField(Key))
293 | {
294 | continue;
295 | }
296 |
297 | SetField(Key, InJsonObject->GetField(Key));
298 | }
299 | }
300 |
301 | UStomtRestJsonObject* UStomtRestJsonObject::GetObjectField(const FString& FieldName) const
302 | {
303 | if (!JsonObj.IsValid())
304 | {
305 | return NULL;
306 | }
307 |
308 | if ( !JsonObj->HasField(FieldName) )
309 | {
310 | return NULL;
311 | }
312 |
313 | TSharedPtr JsonObjField = JsonObj->GetObjectField(FieldName);
314 |
315 | UStomtRestJsonObject* OutRestJsonObj = NewObject();
316 | OutRestJsonObj->SetRootObject(JsonObjField);
317 |
318 | return OutRestJsonObj;
319 | }
320 |
321 | void UStomtRestJsonObject::SetObjectField(const FString& FieldName, UStomtRestJsonObject* JsonObject)
322 | {
323 | if (!JsonObj.IsValid())
324 | {
325 | return;
326 | }
327 |
328 | JsonObj->SetObjectField(FieldName, JsonObject->GetRootObject());
329 | }
330 |
331 |
332 | ////////////////////////////////////////////////////////////////////////////
333 | //// Array fields helpers (uniform arrays)
334 |
335 | TArray UStomtRestJsonObject::GetNumberArrayField(const FString& FieldName)
336 | {
337 | TArray NumberArray;
338 |
339 | if (!JsonObj.IsValid())
340 | {
341 | return NumberArray;
342 | }
343 |
344 | TArray > JsonArrayValues = JsonObj->GetArrayField(FieldName);
345 | for (TArray >::TConstIterator It(JsonArrayValues); It; ++It)
346 | {
347 | NumberArray.Add((*It)->AsNumber());
348 | }
349 |
350 | return NumberArray;
351 | }
352 |
353 | void UStomtRestJsonObject::SetNumberArrayField(const FString& FieldName, const TArray& NumberArray)
354 | {
355 | if (!JsonObj.IsValid())
356 | {
357 | return;
358 | }
359 |
360 | TArray< TSharedPtr > EntriesArray;
361 |
362 | for (auto Number : NumberArray)
363 | {
364 | EntriesArray.Add(MakeShareable(new FJsonValueNumber(Number)));
365 | }
366 |
367 | JsonObj->SetArrayField(FieldName, EntriesArray);
368 | }
369 |
370 | TArray UStomtRestJsonObject::GetStringArrayField(const FString& FieldName)
371 | {
372 | TArray StringArray;
373 |
374 | if (!JsonObj.IsValid())
375 | {
376 | return StringArray;
377 | }
378 |
379 | TArray > JsonArrayValues = JsonObj->GetArrayField(FieldName);
380 | for (TArray >::TConstIterator It(JsonArrayValues); It; ++It)
381 | {
382 | StringArray.Add((*It)->AsString());
383 | }
384 |
385 | return StringArray;
386 | }
387 |
388 | void UStomtRestJsonObject::SetStringArrayField(const FString& FieldName, const TArray& StringArray)
389 | {
390 | if (!JsonObj.IsValid())
391 | {
392 | return;
393 | }
394 |
395 | TArray< TSharedPtr > EntriesArray;
396 |
397 | for (auto String : StringArray)
398 | {
399 | EntriesArray.Add(MakeShareable(new FJsonValueString(String)));
400 | }
401 |
402 | JsonObj->SetArrayField(FieldName, EntriesArray);
403 | }
404 |
405 | TArray UStomtRestJsonObject::GetBoolArrayField(const FString& FieldName)
406 | {
407 | TArray BoolArray;
408 |
409 | if (!JsonObj.IsValid())
410 | {
411 | return BoolArray;
412 | }
413 |
414 | TArray > JsonArrayValues = JsonObj->GetArrayField(FieldName);
415 | for (TArray >::TConstIterator It(JsonArrayValues); It; ++It)
416 | {
417 | BoolArray.Add((*It)->AsBool());
418 | }
419 |
420 | return BoolArray;
421 | }
422 |
423 | void UStomtRestJsonObject::SetBoolArrayField(const FString& FieldName, const TArray& BoolArray)
424 | {
425 | if (!JsonObj.IsValid())
426 | {
427 | return;
428 | }
429 |
430 | TArray< TSharedPtr > EntriesArray;
431 |
432 | for (auto Boolean : BoolArray)
433 | {
434 | EntriesArray.Add(MakeShareable(new FJsonValueBoolean(Boolean)));
435 | }
436 |
437 | JsonObj->SetArrayField(FieldName, EntriesArray);
438 | }
439 |
440 | TArray UStomtRestJsonObject::GetObjectArrayField(const FString& FieldName)
441 | {
442 | TArray OutArray;
443 |
444 | if (!JsonObj.IsValid())
445 | {
446 | return OutArray;
447 | }
448 |
449 | TArray< TSharedPtr > ValArray = JsonObj->GetArrayField(FieldName);
450 | for (auto Value : ValArray)
451 | {
452 | TSharedPtr NewObj = Value->AsObject();
453 |
454 | UStomtRestJsonObject* NewJson = NewObject();
455 | NewJson->SetRootObject(NewObj);
456 |
457 | OutArray.Add(NewJson);
458 | }
459 |
460 | return OutArray;
461 | }
462 |
463 | void UStomtRestJsonObject::SetObjectArrayField(const FString& FieldName, const TArray& ObjectArray)
464 | {
465 | if (!JsonObj.IsValid())
466 | {
467 | return;
468 | }
469 |
470 | TArray< TSharedPtr > EntriesArray;
471 |
472 | for (auto Value : ObjectArray)
473 | {
474 | EntriesArray.Add(MakeShareable(new FJsonValueObject(Value->GetRootObject())));
475 | }
476 |
477 | JsonObj->SetArrayField(FieldName, EntriesArray);
478 | }
479 |
--------------------------------------------------------------------------------
/Source/StomtPlugin/Private/StomtJsonValue.cpp:
--------------------------------------------------------------------------------
1 | // Copyright 2018 STOMT GmbH. All Rights Reserved.
2 | #pragma once
3 |
4 | #include "StomtJsonValue.h"
5 | #include "StomtPluginPrivatePCH.h"
6 |
7 | UStomtJsonValue* UStomtJsonValue::ConstructJsonValueNumber(UObject* WorldContextObject, float Number)
8 | {
9 | TSharedPtr NewVal = MakeShareable(new FJsonValueNumber(Number));
10 |
11 | UStomtJsonValue* NewValue = NewObject();
12 | NewValue->SetRootValue(NewVal);
13 |
14 | return NewValue;
15 | }
16 |
17 | UStomtJsonValue* UStomtJsonValue::ConstructJsonValueString(UObject* WorldContextObject, const FString& StringValue)
18 | {
19 | TSharedPtr NewVal = MakeShareable(new FJsonValueString(StringValue));
20 |
21 | UStomtJsonValue* NewValue = NewObject();
22 | NewValue->SetRootValue(NewVal);
23 |
24 | return NewValue;
25 | }
26 |
27 | UStomtJsonValue* UStomtJsonValue::ConstructJsonValueBool(UObject* WorldContextObject, bool InValue)
28 | {
29 | TSharedPtr NewVal = MakeShareable(new FJsonValueBoolean(InValue));
30 |
31 | UStomtJsonValue* NewValue = NewObject();
32 | NewValue->SetRootValue(NewVal);
33 |
34 | return NewValue;
35 | }
36 |
37 | UStomtJsonValue* UStomtJsonValue::ConstructJsonValueArray(UObject* WorldContextObject, const TArray& InArray)
38 | {
39 | // Prepare data array to create new value
40 | TArray< TSharedPtr > ValueArray;
41 | for (auto InVal : InArray)
42 | {
43 | ValueArray.Add(InVal->GetRootValue());
44 | }
45 |
46 | TSharedPtr NewVal = MakeShareable(new FJsonValueArray(ValueArray));
47 |
48 | UStomtJsonValue* NewValue = NewObject();
49 | NewValue->SetRootValue(NewVal);
50 |
51 | return NewValue;
52 | }
53 |
54 | UStomtJsonValue* ConstructJsonValue(UObject* WorldContextObject, const TSharedPtr& InValue)
55 | {
56 | TSharedPtr NewVal = InValue;
57 |
58 | UStomtJsonValue* NewValue = NewObject();
59 | NewValue->SetRootValue(NewVal);
60 |
61 | return NewValue;
62 | }
63 |
64 | TSharedPtr& UStomtJsonValue::GetRootValue()
65 | {
66 | return JsonVal;
67 | }
68 |
69 | void UStomtJsonValue::SetRootValue(TSharedPtr& JsonValue)
70 | {
71 | JsonVal = JsonValue;
72 | }
73 |
74 |
75 | ////////////////////////////////////////////////////////////////////////////
76 | //// FJsonValue API
77 |
78 | StomtEnumJson::Type UStomtJsonValue::GetType() const
79 | {
80 | if (!(JsonVal.IsValid()))
81 | {
82 | return StomtEnumJson::None;
83 | }
84 |
85 | switch (JsonVal->Type)
86 | {
87 | case EJson::None:
88 | return StomtEnumJson::None;
89 |
90 | case EJson::Null:
91 | return StomtEnumJson::Null;
92 |
93 | case EJson::String:
94 | return StomtEnumJson::String;
95 |
96 | case EJson::Number:
97 | return StomtEnumJson::Number;
98 |
99 | case EJson::Boolean:
100 | return StomtEnumJson::Boolean;
101 |
102 | case EJson::Array:
103 | return StomtEnumJson::Array;
104 |
105 | case EJson::Object:
106 | return StomtEnumJson::Object;
107 |
108 | default:
109 | return StomtEnumJson::None;
110 | }
111 | }
112 |
113 | FString UStomtJsonValue::GetTypeString() const
114 | {
115 | if (!JsonVal.IsValid())
116 | {
117 | return "None";
118 | }
119 |
120 | switch (JsonVal->Type)
121 | {
122 | case EJson::None:
123 | return TEXT("None");
124 |
125 | case EJson::Null:
126 | return TEXT("Null");
127 |
128 | case EJson::String:
129 | return TEXT("String");
130 |
131 | case EJson::Number:
132 | return TEXT("Number");
133 |
134 | case EJson::Boolean:
135 | return TEXT("Boolean");
136 |
137 | case EJson::Array:
138 | return TEXT("Array");
139 |
140 | case EJson::Object:
141 | return TEXT("Object");
142 |
143 | default:
144 | return TEXT("None");
145 | }
146 | }
147 |
148 | bool UStomtJsonValue::IsNull() const
149 | {
150 | if (!JsonVal.IsValid())
151 | {
152 | return true;
153 | }
154 |
155 | return JsonVal->IsNull();
156 | }
157 |
158 | float UStomtJsonValue::AsNumber() const
159 | {
160 | if (!JsonVal.IsValid())
161 | {
162 | ErrorMessage(TEXT("Number"));
163 | return 0.f;
164 | }
165 |
166 | return JsonVal->AsNumber();
167 | }
168 |
169 | FString UStomtJsonValue::AsString() const
170 | {
171 | if (!JsonVal.IsValid())
172 | {
173 | ErrorMessage(TEXT("String"));
174 | return FString();
175 | }
176 |
177 | return JsonVal->AsString();
178 | }
179 |
180 | bool UStomtJsonValue::AsBool() const
181 | {
182 | if (!JsonVal.IsValid())
183 | {
184 | ErrorMessage(TEXT("Boolean"));
185 | return false;
186 | }
187 |
188 | return JsonVal->AsBool();
189 | }
190 |
191 | TArray UStomtJsonValue::AsArray() const
192 | {
193 | TArray OutArray;
194 |
195 | if (!JsonVal.IsValid())
196 | {
197 | ErrorMessage(TEXT("Array"));
198 | return OutArray;
199 | }
200 |
201 | TArray< TSharedPtr > ValArray = JsonVal->AsArray();
202 | for (auto Value : ValArray)
203 | {
204 | UStomtJsonValue* NewValue = NewObject();
205 | NewValue->SetRootValue(Value);
206 |
207 | OutArray.Add(NewValue);
208 | }
209 |
210 | return OutArray;
211 | }
212 |
213 |
214 | //
215 | ////////////////////////////////////////////////////////////////////////////
216 | //// Helpers
217 | //
218 | void UStomtJsonValue::ErrorMessage(const FString& InType) const
219 | {
220 | UE_LOG(StomtLog, Error, TEXT("Json Value of type '%s' used as a '%s'."), *GetTypeString(), *InType);
221 | }
222 |
--------------------------------------------------------------------------------
/Source/StomtPlugin/Private/StomtLabel.cpp:
--------------------------------------------------------------------------------
1 | // Copyright 2018 STOMT GmbH. All Rights Reserved.
2 | #pragma once
3 |
4 | #include "StomtLabel.h"
5 | #include "StomtPluginPrivatePCH.h"
6 |
7 | //////////////////////////////////////////////////////////////////////////
8 | // Construction
9 |
10 | UStomtLabel::UStomtLabel()
11 | {
12 | // Default
13 | /*
14 | this->Color = FString("#5EBEFF");
15 | this->bIsPublic = false;
16 | this->bAsTargetOwner = false;
17 | */
18 | }
19 |
20 | //////////////////////////////////////////////////////////////////////////
21 | // Data accessors
22 |
23 | UStomtLabel * UStomtLabel::ConstructLabel(FString NewName)
24 | {
25 | UStomtLabel* StomtLabel = NewObject();
26 | StomtLabel->SetName(NewName);
27 |
28 | return StomtLabel;
29 | }
30 |
31 | void UStomtLabel::SetName(FString NewName)
32 | {
33 | this->Name = NewName;
34 | }
35 |
36 | void UStomtLabel::SetColor(FString NewColor)
37 | {
38 | this->Color = NewColor;
39 | }
40 |
41 | void UStomtLabel::SetIsPublic(bool bNewIsPublic)
42 | {
43 | this->bIsPublic = bNewIsPublic;
44 | }
45 |
46 | void UStomtLabel::SetAsTargetOwner(bool bNewAsTargetOwner)
47 | {
48 | this->bAsTargetOwner = bNewAsTargetOwner;
49 | }
50 |
51 | FString UStomtLabel::GetName()
52 | {
53 | return this->Name;
54 | }
55 |
56 | FString UStomtLabel::GetColor()
57 | {
58 | return this->Color;
59 | }
60 |
61 | bool UStomtLabel::GetIsPublic()
62 | {
63 | return this->bIsPublic;
64 | }
65 |
66 | bool UStomtLabel::GetAsTargetOwner()
67 | {
68 | return this->bAsTargetOwner;
69 | }
70 |
--------------------------------------------------------------------------------
/Source/StomtPlugin/Private/StomtPlugin.cpp:
--------------------------------------------------------------------------------
1 | // Copyright 2018 STOMT GmbH. All Rights Reserved.
2 | #pragma once
3 | #include "StomtPlugin.h"
4 | #include "StomtPluginPrivatePCH.h"
5 |
6 | class FStomtPlugin : public StomtPlugin
7 | {
8 | /** IModuleInterface implementation */
9 | virtual void StartupModule() override
10 | {
11 | //Force classes to be compiled on shipping build
12 | }
13 |
14 | virtual void ShutdownModule() override
15 | {
16 |
17 | }
18 | };
19 |
20 | IMPLEMENT_MODULE(FStomtPlugin, StomtPlugin);
21 |
22 | DEFINE_LOG_CATEGORY(StomtLog);
23 | DEFINE_LOG_CATEGORY(StomtNetwork);
24 | DEFINE_LOG_CATEGORY(StomtInit);
25 | DEFINE_LOG_CATEGORY(StomtFileAccess);
26 |
--------------------------------------------------------------------------------
/Source/StomtPlugin/Private/StomtPluginWidget.cpp:
--------------------------------------------------------------------------------
1 | // Copyright 2018 STOMT GmbH. All Rights Reserved.
2 | #pragma once
3 |
4 | #include "StomtPluginWidget.h"
5 | #include "StomtPluginPrivatePCH.h"
6 | #include "StomtRestRequest.h"
7 | #include "StomtLabel.h"
8 |
9 | #include "Runtime/Engine/Classes/Components/SceneCaptureComponent2D.h"
10 |
11 | UStomtPluginWidget::~UStomtPluginWidget()
12 | {
13 | this->LoginErrorCode = 0;
14 | }
15 |
16 | void UStomtPluginWidget::OnConstruction(FString AppId)
17 | {
18 | // Create API Object
19 | if (this->Api == NULL)
20 | {
21 | this->Api = UStomtAPI::ConstructStomtAPI(AppId);
22 | }
23 | else
24 | {
25 | this->Api->SetAppId(AppId);
26 | }
27 |
28 | this->Config = this->Api->Config;
29 |
30 | // Request User
31 | this->Api->RequestSession();
32 |
33 | // Request Target Name
34 | UStomtRestRequest* Request = this->Api->RequestTargetByAppId();
35 | Request->OnRequestComplete.AddDynamic(this, &UStomtPluginWidget::OnTargetResponse);
36 |
37 | // Lookup E-Mail
38 | this->bIsEMailAlreadyKnown = this->Api->Config->GetSubscribed();
39 | this->bIsUserLoggedIn = this->Api->Config->GetLoggedIn();
40 | }
41 |
42 | void UStomtPluginWidget::OnMessageChanged(FString text)
43 | {
44 | if (!text.IsEmpty())
45 | {
46 | this->Message = text;
47 | }
48 | else
49 | {
50 | this->Message = FString(TEXT(""));
51 | }
52 | }
53 |
54 |
55 | void UStomtPluginWidget::OnDetailsCommitted(FString text)
56 | {
57 | if (!text.IsEmpty())
58 | {
59 | this->Details = text;
60 | }
61 | else
62 | {
63 | this->Details = FString(TEXT(""));
64 | }
65 | }
66 |
67 | void UStomtPluginWidget::OnSubmit()
68 | {
69 | if (this->Message.IsEmpty())
70 | {
71 | return;
72 | }
73 |
74 | // Check EMail
75 | this->bIsEMailAlreadyKnown = this->Api->Config->GetSubscribed();
76 | UE_LOG(StomtLog, Log, TEXT("Is EMail Already Known: %s"), this->bIsEMailAlreadyKnown ? TEXT("true") : TEXT("false"));
77 |
78 | // Create Stomt Instance
79 | this->Stomt = UStomt::ConstructStomt(this->Api->GetTargetId(), !this->bIsWish, this->Message, this->Details);
80 | this->Stomt->SetLabels(this->Labels);
81 | this->Stomt->SetAnonym(false);
82 |
83 | this->Api->SetStomtToSend(this->Stomt);
84 | this->Api->HandleOfflineStomts();
85 |
86 | if (this->bUploadLogs)
87 | {
88 | FString LogFileName = FApp::GetProjectName() + FString(TEXT(".log"));
89 | FString LogFile = this->Api->ReadLogFile(LogFileName);
90 | if (!LogFile.IsEmpty())
91 | {
92 | this->Api->SendLogFile(LogFile, LogFileName);
93 | return;
94 | }
95 | }
96 |
97 | this->Api->bIsLogUploadComplete = true;
98 | if (!this->Api->bUseImageUpload)
99 | {
100 | this->Api->SendStomt(this->Stomt);
101 | } // else Screenhot Upload is triggered by blueprint
102 | }
103 |
104 | void UStomtPluginWidget::OnSubmitLastLayer()
105 | {
106 |
107 | }
108 |
109 | bool UStomtPluginWidget::OnSubmitLogin()
110 | {
111 | if (!this->UserName.IsEmpty() && !this->UserPassword.IsEmpty())
112 | {
113 | UStomtRestRequest* Request = this->Api->SendLoginRequest(this->UserName, this->UserPassword);
114 | Request->OnRequestComplete.AddDynamic(this, &UStomtPluginWidget::OnLoginResponse);
115 | this->LoginErrorCode = 0;
116 | return true;
117 | }
118 | else
119 | {
120 | return false;
121 | }
122 | }
123 |
124 | void UStomtPluginWidget::OnSubmitEMail()
125 | {
126 | if (!this->EMail.IsEmpty())
127 | {
128 | this->Api->SendSubscription(this->EMail, !this->bUsePhoneNumber);
129 | }
130 | }
131 |
132 | void UStomtPluginWidget::OnLogout()
133 | {
134 | this->Api->SendLogoutRequest();
135 | }
136 |
137 | void UStomtPluginWidget::OnLoginResponse(UStomtRestRequest * LoginRequest)
138 | {
139 | this->LoginErrorCode = LoginRequest->GetResponseCode();
140 | this->bIsUserLoggedIn = this->Api->Config->GetLoggedIn();
141 | this->Api->OnLoginRequestComplete.Broadcast(LoginRequest);
142 | }
143 |
144 | void UStomtPluginWidget::OnTargetResponse(UStomtRestRequest * TargetRequest)
145 | {
146 | this->TargetName = this->Api->GetTargetName();
147 |
148 | UE_LOG(StomtLog, Log, TEXT("OnTargetResponse: %s"), *this->TargetName);
149 |
150 | this->ImageUrl = this->Api->GetImageUrl();
151 |
152 | this->Api->OnTargetRequestComplete.Broadcast(TargetRequest);
153 | }
154 |
155 | FString UStomtPluginWidget::AppendStomtURLParams(FString Url, FString UtmContent)
156 | {
157 | Url += FString("?utm_source=" + FString("stomt"));
158 | Url += FString("&utm_medium=" + FString("sdk"));
159 | Url += FString("&utm_campaign=" + FString("unreal"));
160 | Url += FString("&utm_term=" + FString(FApp::GetProjectName()) );
161 |
162 | if (!UtmContent.IsEmpty())
163 | {
164 | Url += FString("&utm_content=" + UtmContent);
165 | }
166 |
167 | if (!this->Api->Config->GetAccessToken().IsEmpty())
168 | {
169 | Url += FString("&accesstoken=" + this->Api->Config->GetAccessToken());
170 | }
171 |
172 | return Url;
173 | }
174 |
175 | void UStomtPluginWidget::UploadScreenshot()
176 | {
177 | this->Api->SendImageFile(this->Api->ReadScreenshotAsBase64());
178 | }
179 |
--------------------------------------------------------------------------------
/Source/StomtPlugin/Private/StomtRestRequest.cpp:
--------------------------------------------------------------------------------
1 | // Copyright 2018 STOMT GmbH. All Rights Reserved.
2 | #pragma once
3 |
4 | #include "StomtRestRequest.h"
5 | #include "StomtPluginPrivatePCH.h"
6 |
7 | //////////////////////////////////////////////////////////////////////////
8 | // Construction
9 |
10 | UStomtRestRequest::UStomtRestRequest()
11 | {
12 | this->bUseStaticJsonString = false;
13 | this->UseRequestLogging(true);
14 | this->ResponseJsonObj = NULL;
15 | this->RequestJsonObj = NULL;
16 | this->ResetData();
17 | }
18 |
19 | UStomtRestRequest::~UStomtRestRequest()
20 | {
21 | }
22 |
23 |
24 | UStomtRestRequest * UStomtRestRequest::ConstructRequest()
25 | {
26 | return nullptr;
27 | }
28 |
29 | void UStomtRestRequest::SetVerb(StomtEnumRequestVerb::Type Verb)
30 | {
31 | this->RequestVerb = Verb;
32 | }
33 |
34 | void UStomtRestRequest::SetHeader(const FString &HeaderName, const FString &HeaderValue)
35 | {
36 | this->RequestHeaders.Add(HeaderName, HeaderValue);
37 | }
38 |
39 | void UStomtRestRequest::OnResponseReceived(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
40 | {
41 | // Check we have result to process futher
42 | if (!bWasSuccessful)
43 | {
44 | UE_LOG(StomtNetwork, Error, TEXT("Request failed: %s ResponseCode: %d "), *Request->GetURL(), *Response->GetContentAsString());
45 |
46 | // Broadcast the result event
47 | this->OnRequestFail.Broadcast(this);
48 | return;
49 | }
50 |
51 | if (EHttpResponseCodes::IsOk(Response->GetResponseCode()))
52 | {
53 | UE_LOG(StomtNetwork, Log, TEXT("EHttpResponseCodes::IsOk"));
54 | UE_LOG(StomtNetwork, Log, TEXT("Content: %s"), *Response->GetContentAsString() );
55 | }
56 | else
57 | {
58 | UE_LOG(StomtNetwork, Warning, TEXT( "not successful: %s"), *Response->GetContentAsString() );
59 | }
60 |
61 | return;
62 | }
63 |
64 | //////////////////////////////////////////////////////////////////////////
65 | // Helpers
66 |
67 |
68 |
69 | ///////////////////////////////////////////////////////////////////////////
70 | // Response data access
71 |
72 | int32 UStomtRestRequest::GetResponseCode()
73 | {
74 | return this->ResponseCode;
75 | }
76 |
77 | FString UStomtRestRequest::GetResponseHeader(const FString HeaderName)
78 | {
79 | FString Result;
80 |
81 | FString* Header = ResponseHeaders.Find(HeaderName);
82 | if (Header != NULL)
83 | {
84 | Result = *Header;
85 | }
86 |
87 | return Result;
88 | }
89 |
90 |
91 | TArray UStomtRestRequest::GetAllResponseHeaders()
92 | {
93 | TArray Result;
94 |
95 | for (TMap::TConstIterator It(ResponseHeaders); It; ++It)
96 | {
97 | Result.Add(It.Key() + TEXT(": ") + It.Value());
98 | }
99 |
100 | return Result;
101 | }
102 |
103 | //////////////////////////////////////////////////////////////////////////
104 | // URL processing
105 |
106 | void UStomtRestRequest::ProcessUrl(const FString& Url)
107 | {
108 | // Signature changed from version 4.25 to 4.26 (ThreadSafe)
109 | auto HttpRequest = FHttpModule::Get().CreateRequest();
110 | HttpRequest->SetURL(Url);
111 |
112 | // Set verb
113 | switch (RequestVerb)
114 | {
115 | case StomtEnumRequestVerb::GET:
116 | HttpRequest->SetVerb(TEXT("GET"));
117 | break;
118 |
119 | case StomtEnumRequestVerb::POST:
120 | HttpRequest->SetVerb(TEXT("POST"));
121 | break;
122 |
123 | case StomtEnumRequestVerb::PUT:
124 | HttpRequest->SetVerb(TEXT("PUT"));
125 | break;
126 |
127 | case StomtEnumRequestVerb::DEL:
128 | HttpRequest->SetVerb(TEXT("DELETE"));
129 | break;
130 |
131 | default:
132 | break;
133 | }
134 |
135 | HttpRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
136 |
137 | // Serialize data to json string
138 | FString OutputString;
139 | TSharedRef< TJsonWriter<> > Writer = TJsonWriterFactory<>::Create(&OutputString);
140 | FJsonSerializer::Serialize(this->RequestJsonObj->GetRootObject().ToSharedRef(), Writer);
141 |
142 |
143 | // Set Json content
144 | if ( !HttpRequest->GetVerb().Equals( TEXT("GET") ) )
145 | {
146 | if (this->bUseStaticJsonString)
147 | {
148 | if (!this->StaticJsonOutputString.IsEmpty())
149 | {
150 | OutputString = this->StaticJsonOutputString;
151 | }
152 | }
153 |
154 | HttpRequest->SetContentAsString(OutputString);
155 | }
156 |
157 | if (this->bRequestLogging)
158 | {
159 | if (OutputString.Len() > 256)
160 | {
161 | FString shortContent = OutputString.LeftChop(OutputString.Len() - 256);
162 | UE_LOG(StomtNetwork, Log, TEXT("Request (json): %s %s | truncated-content(256): %s"), *HttpRequest->GetVerb(), *HttpRequest->GetURL(), *shortContent);
163 | }
164 | else
165 | {
166 | UE_LOG(StomtNetwork, Log, TEXT("Request (json): %s %s %s"), *HttpRequest->GetVerb(), *HttpRequest->GetURL(), *OutputString);
167 | }
168 | }
169 | else
170 | {
171 | UE_LOG(StomtNetwork, Log, TEXT("Request (json): %s %s | did not log (contains user data)"), *HttpRequest->GetVerb(), *HttpRequest->GetURL());
172 | }
173 |
174 |
175 |
176 | // Apply additional headers
177 | for (TMap::TConstIterator It(RequestHeaders); It; ++It)
178 | {
179 | HttpRequest->SetHeader(It.Key(), It.Value());
180 | }
181 |
182 | // Bind event
183 | HttpRequest->OnProcessRequestComplete().BindUObject(this, &UStomtRestRequest::OnProcessRequestComplete);
184 |
185 | // Execute the Request
186 | HttpRequest->ProcessRequest();
187 | }
188 |
189 |
190 | //////////////////////////////////////////////////////////////////////////
191 | // Request callbacks
192 |
193 |
194 | void UStomtRestRequest::OnProcessRequestComplete(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
195 | {
196 | // Be sure that we have no data from previous response
197 | this->ResetResponseData();
198 |
199 | // Check we have result to process futher
200 | if (!bWasSuccessful)
201 | {
202 | UE_LOG(StomtNetwork, Error, TEXT("Request failed: %s"), *Request->GetURL());
203 |
204 | // Broadcast the result event
205 | this->OnRequestFail.Broadcast(this);
206 | return;
207 | }
208 |
209 | // Save response data as a string
210 | this->ResponseContent = Response->GetContentAsString();
211 |
212 | // Save response code as int32
213 | this->ResponseCode = Response->GetResponseCode();
214 |
215 | // Log response state
216 |
217 | if (Response->GetContentAsString().Len() > 256)
218 | {
219 | FString shortContent = Response->GetContentAsString().LeftChop(Response->GetContentAsString().Len() - 256);
220 | UE_LOG(StomtNetwork, Log, TEXT("Response (%d): Content(truncated 256): %s"), Response->GetResponseCode(), *shortContent);
221 | }
222 | else
223 | {
224 | UE_LOG(StomtNetwork, Log, TEXT("Response (%d): %s"), Response->GetResponseCode(), *Response->GetContentAsString());
225 | }
226 |
227 |
228 | // Process response headers
229 | TArray Headers = Response->GetAllHeaders();
230 | for (FString Header : Headers)
231 | {
232 | FString Key;
233 | FString Value;
234 | if (Header.Split(TEXT(": "), &Key, &Value))
235 | {
236 | this->ResponseHeaders.Add(Key, Value);
237 | }
238 | }
239 |
240 | // Try to deserialize data to JSON
241 | TSharedRef> JsonReader = TJsonReaderFactory::Create(this->ResponseContent);
242 | FJsonSerializer::Deserialize(JsonReader, this->ResponseJsonObj->GetRootObject());
243 |
244 | // Decide whether the Request was successful
245 | this->bIsValidJsonResponse = bWasSuccessful && this->ResponseJsonObj->GetRootObject().IsValid();
246 |
247 | // Log errors
248 | if (!this->bIsValidJsonResponse)
249 | {
250 | if (!this->ResponseJsonObj->GetRootObject().IsValid())
251 | {
252 | // As we assume it's recommended way to use current class, but not the only one,
253 | // it will be the warning instead of error
254 | UE_LOG(StomtNetwork, Warning, TEXT("JSON could not be decoded!"));
255 | }
256 | }
257 |
258 | // Broadcast the result event
259 | this->OnRequestComplete.Broadcast(this);
260 |
261 | // Finish the latent action
262 | if (this->ContinueAction)
263 | {
264 | StomtLatentAction *K = this->ContinueAction;
265 | this->ContinueAction = nullptr;
266 |
267 | K->Call(this->ResponseJsonObj);
268 | }
269 | }
270 |
271 | void UStomtRestRequest::UseStaticJsonString(bool bNewUseStaticJsonString)
272 | {
273 | this->bUseStaticJsonString = bNewUseStaticJsonString;
274 | }
275 |
276 | void UStomtRestRequest::UseRequestLogging(bool bNewRequestLogging)
277 | {
278 | this->bRequestLogging = bNewRequestLogging;
279 | }
280 |
281 | void UStomtRestRequest::SetStaticJsonString(FString JsonString)
282 | {
283 | this->StaticJsonOutputString = JsonString;
284 | }
285 |
286 | //////////////////////////////////////////////////////////////////////////
287 | // Destruction and reset
288 |
289 | void UStomtRestRequest::ResetData()
290 | {
291 | this->ResetRequestData();
292 | this->ResetResponseData();
293 | }
294 |
295 | void UStomtRestRequest::ResetRequestData()
296 | {
297 | if (this->RequestJsonObj != NULL)
298 | {
299 | this->RequestJsonObj->Reset();
300 | }
301 | else
302 | {
303 | this->RequestJsonObj = NewObject();
304 | }
305 |
306 | this->bUseStaticJsonString = false;
307 | }
308 |
309 | void UStomtRestRequest::ResetResponseData()
310 | {
311 | if (this->ResponseJsonObj != NULL)
312 | {
313 | this->ResponseJsonObj->Reset();
314 | }
315 | else
316 | {
317 | this->ResponseJsonObj = NewObject();
318 | }
319 |
320 | this->ResponseHeaders.Empty();
321 | this->ResponseCode = -1;
322 |
323 | this->bIsValidJsonResponse = false;
324 | }
325 |
326 |
327 | //////////////////////////////////////////////////////////////////////////
328 | // JSON data accessors
329 |
330 | UStomtRestJsonObject* UStomtRestRequest::GetRequestObject()
331 | {
332 | return this->RequestJsonObj;
333 | }
334 |
335 | void UStomtRestRequest::SetRequestObject(UStomtRestJsonObject* JsonObject)
336 | {
337 | this->RequestJsonObj = JsonObject;
338 | }
339 |
340 | UStomtRestJsonObject* UStomtRestRequest::GetResponseObject()
341 | {
342 | return this->ResponseJsonObj;
343 | }
344 |
345 | void UStomtRestRequest::SetResponseObject(UStomtRestJsonObject* JsonObject)
346 | {
347 | ResponseJsonObj = JsonObject;
348 | }
349 |
--------------------------------------------------------------------------------
/Source/StomtPlugin/Private/StomtTrack.cpp:
--------------------------------------------------------------------------------
1 | // Copyright 2018 STOMT GmbH. All Rights Reserved.
2 | #pragma once
3 |
4 | #include "StomtTrack.h"
5 | #include "StomtPluginPrivatePCH.h"
6 | #include "StomtJsonObject.h"
7 |
8 | #include "Runtime/Core/Public/Misc/FileHelper.h"
9 | #include "Runtime/Core/Public/Misc/Paths.h"
10 | #include "Runtime/Core/Public/GenericPlatform/GenericPlatformFile.h"
11 | #include "Runtime/Core/Public/Misc/App.h"
12 | #include "Runtime/Engine/Classes/Kismet/GameplayStatics.h"
13 | #include "Runtime/Engine/Classes/Kismet/KismetSystemLibrary.h"
14 | #include "Runtime/Core/Public/GenericPlatform/GenericPlatformProcess.h"
15 | #include "Runtime/Engine/Classes/Kismet/KismetSystemLibrary.h"
16 |
17 | UStomtTrack* UStomtTrack::ConstructStomtTrack()
18 | {
19 | UStomtTrack* Track = NewObject();
20 | return Track;
21 | }
22 |
23 | UStomtTrack::UStomtTrack()
24 | {
25 | UE_LOG(StomtInit, Log, TEXT("Constuct Stomt Sdk Track"));
26 |
27 | this->SetDevicePlatform(UGameplayStatics::GetPlatformName());
28 | UE_LOG(StomtInit, Log, TEXT("DevicePlatform: %s"), *this->DevicePlatform);
29 |
30 | this->SetDeviceId(FGenericPlatformProcess::ComputerName());
31 | UE_LOG(StomtInit, Log, TEXT("DeviceId: %s"), *this->DeviceId);
32 |
33 | this->SetSdkType(FString("UnrealEngine") + UKismetSystemLibrary::GetEngineVersion());
34 | UE_LOG(StomtInit, Log, TEXT("SdkType: %s"), *this->SdkType);
35 |
36 | this->SetSdkVersion("2.5.1");
37 | UE_LOG(StomtInit, Log, TEXT("SdkVersion: %s"), *this->SdkVersion);
38 |
39 | this->SetSdkIntegration(UKismetSystemLibrary::GetGameName());
40 | UE_LOG(StomtInit, Log, TEXT("SdkIntegration: %s"), *this->SdkIntegration);
41 | }
42 |
43 | UStomtTrack::~UStomtTrack()
44 | {
45 |
46 | }
47 |
48 | UStomtRestJsonObject * UStomtTrack::GetAsJsonObject()
49 | {
50 | UStomtRestJsonObject* JsonObj = UStomtRestJsonObject::ConstructJsonObject(this);
51 |
52 | if (!this->DevicePlatform.IsEmpty())
53 | {
54 | JsonObj->SetStringField("device_platform", this->DevicePlatform);
55 | }
56 |
57 | if (!this->DeviceId.IsEmpty())
58 | {
59 | JsonObj->SetStringField("device_id", this->DeviceId);
60 | }
61 |
62 | if (!this->SdkType.IsEmpty())
63 | {
64 | JsonObj->SetStringField("sdk_type", this->SdkType);
65 | }
66 |
67 | if (!this->SdkVersion.IsEmpty())
68 | {
69 | JsonObj->SetStringField("sdk_version", this->SdkVersion);
70 | }
71 |
72 | if (!this->SdkIntegration.IsEmpty())
73 | {
74 | JsonObj->SetStringField("sdk_integration", this->SdkIntegration);
75 | }
76 |
77 | if (!this->TargetId.IsEmpty())
78 | {
79 | JsonObj->SetStringField("target_id", this->TargetId);
80 | }
81 |
82 | if (!this->StomtId.IsEmpty())
83 | {
84 | JsonObj->SetStringField("stomt_id", this->StomtId);
85 | }
86 |
87 | if (!this->EventCategory.IsEmpty())
88 | {
89 | JsonObj->SetStringField("event_category", this->EventCategory);
90 | }
91 |
92 | if (!this->EventAction.IsEmpty())
93 | {
94 | JsonObj->SetStringField("event_action", this->EventAction);
95 | }
96 |
97 | if (!this->EventLabel.IsEmpty())
98 | {
99 | JsonObj->SetStringField("event_label", this->EventLabel);
100 | }
101 |
102 | return JsonObj;
103 | }
104 |
105 | void UStomtTrack::SetDevicePlatform(FString NewDevicePlatform)
106 | {
107 | this->DevicePlatform = NewDevicePlatform;
108 | }
109 |
110 | void UStomtTrack::SetDeviceId(FString NewDeviceId)
111 | {
112 | this->DeviceId = NewDeviceId;
113 | }
114 |
115 | void UStomtTrack::SetSdkType(FString NewSdkType)
116 | {
117 | this->SdkType = NewSdkType;
118 | }
119 |
120 | void UStomtTrack::SetSdkVersion(FString NewSdkVersion)
121 | {
122 | this->SdkVersion = NewSdkVersion;
123 | }
124 |
125 | void UStomtTrack::SetSdkIntegration(FString NewSdkIntegration)
126 | {
127 | this->SdkIntegration = NewSdkIntegration;
128 | }
129 |
130 | void UStomtTrack::SetTargetId(FString NewTargetId)
131 | {
132 | this->TargetId = NewTargetId;
133 | }
134 |
135 | void UStomtTrack::SetStomtId(FString NewStomtId)
136 | {
137 | this->StomtId = NewStomtId;
138 | }
139 |
140 | void UStomtTrack::SetEventCategory(FString NewEventCategory)
141 | {
142 | this->EventCategory = NewEventCategory;
143 | }
144 |
145 | void UStomtTrack::SetEventAction(FString NewEventAction)
146 | {
147 | this->EventAction = NewEventAction;
148 | }
149 |
150 | void UStomtTrack::SetEventLabel(FString NewEventLabel)
151 | {
152 | this->EventLabel = NewEventLabel;
153 | }
154 |
--------------------------------------------------------------------------------
/Source/StomtPlugin/Public/Stomt.h:
--------------------------------------------------------------------------------
1 | // Copyright 2018 STOMT GmbH. All Rights Reserved.
2 | #pragma once
3 |
4 | #include "StomtPluginPrivatePCH.h"
5 | #include "StomtRestRequest.h"
6 | #include "StomtLabel.h"
7 | #include "Stomt.generated.h"
8 |
9 | UCLASS()
10 | class STOMTPLUGIN_API UStomt : public UObject
11 | {
12 | GENERATED_BODY()
13 |
14 | public:
15 | //////////////////////////////////////////////////////////////////////////
16 | // Construction
17 |
18 | UStomt();
19 |
20 | /**
21 | * Creates new Stomt object
22 | * @param NewTargetId - Stomt target Id
23 | * @param bNewPositive - whether it is wish(false) or like(true)
24 | * @param NewText - Stomt content text.
25 | * @param NewDetails - Stomt details text.
26 | */
27 | static UStomt* ConstructStomt(FString NewTargetId, bool bNewPositive, FString NewText, FString NewDetails);
28 |
29 | //////////////////////////////////////////////////////////////////////////
30 | // Destruction and reset
31 | //TODO reset functions
32 |
33 | //////////////////////////////////////////////////////////////////////////
34 | // Data accessors
35 |
36 | void SetTargetId(FString NewTargetId);
37 |
38 | void SetPositive(bool bNewPositive);
39 |
40 | void SetText(FString NewText);
41 |
42 | void SetDetails(FString NewDetails);
43 |
44 | void SetAnonym(bool bNewAnonym);
45 |
46 | void SetServersideId(FString NewServersideId);
47 |
48 | // Labels
49 | void AddLabel(UStomtLabel* NewLabel);
50 |
51 | void SetLabels(TArray NewLabels);
52 |
53 | void SetLabels(TArray NewLabels);
54 |
55 | FString GetTargetId();
56 |
57 | bool GetPositive();
58 |
59 | FString GetText();
60 |
61 | FString GetDetails();
62 |
63 | bool GetAnonym();
64 |
65 | TArray GetLabels();
66 |
67 | FString GetServersideId();
68 |
69 |
70 |
71 | //////////////////////////////////////////////////////////////////////////
72 | // Data
73 |
74 | private:
75 | UPROPERTY()
76 | FString ServersideId;
77 |
78 | UPROPERTY()
79 | FString TargetId;
80 |
81 | UPROPERTY()
82 | bool bPositive;
83 |
84 | UPROPERTY()
85 | FString Text;
86 |
87 | UPROPERTY()
88 | FString Url;
89 |
90 | UPROPERTY()
91 | FString Details;
92 |
93 | UPROPERTY()
94 | bool bAnonym;
95 |
96 | UPROPERTY()
97 | FString ImgName;
98 |
99 | UPROPERTY()
100 | FString LonLat;
101 |
102 | UPROPERTY()
103 | TArray Labels;
104 | };
105 |
--------------------------------------------------------------------------------
/Source/StomtPlugin/Public/StomtAPI.h:
--------------------------------------------------------------------------------
1 | // Copyright 2018 STOMT GmbH. All Rights Reserved.
2 | #pragma once
3 |
4 | #include "StomtPluginPrivatePCH.h"
5 | #include "StomtRestRequest.h"
6 | #include "Stomt.h"
7 | #include "StomtConfig.h"
8 | #include "StomtTrack.h"
9 | #include "Runtime/Engine/Classes/Engine/TextureRenderTarget2D.h"
10 | #include "StomtAPI.generated.h"
11 |
12 | DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnTargetRequestComplete, class UStomtRestRequest*, Request);
13 | DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnLoginRequestComplete, class UStomtRestRequest*, Request);
14 | DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnRequestFailed, class UStomtRestRequest*, Request);
15 |
16 | UCLASS()
17 | class STOMTPLUGIN_API UStomtAPI : public UObject
18 | {
19 | GENERATED_BODY()
20 |
21 | public:
22 |
23 | static UStomtAPI* ConstructStomtAPI(FString AppId);
24 |
25 | UStomtAPI();
26 |
27 | ~UStomtAPI();
28 |
29 | /**
30 | * Sends a stomt.
31 | * @param stomt - Stomt Object with some content.
32 | */
33 | void SendStomt(UStomt* Stomt);
34 |
35 | //////////////////////////////////////////////////////////////////////////
36 | // Data accessors
37 |
38 | /**
39 | * Sets the STOMT REST API Server URL.
40 | * For example: https://rest.stomt.com
41 | * @param URL - Stomt REST URL
42 | */
43 | UFUNCTION(BlueprintCallable, Category = "Stomt API")
44 | void SetRestUrl(FString NewRestUrl);
45 |
46 | UFUNCTION(BlueprintCallable, Category = "Stomt API")
47 | FString GetRestUrl();
48 |
49 | /**
50 | * Sets the STOMT Website Server URL.
51 | * For example: https://www.stomt.com
52 | * @param URL - Stomt REST URL
53 | */
54 | UFUNCTION(BlueprintCallable, Category = "Stomt API")
55 | void SetStomtUrl(FString NewStomtUrl);
56 |
57 | UFUNCTION(BlueprintCallable, Category = "Stomt API")
58 | FString GetStomtUrl();
59 |
60 | /**
61 | * Sets the Stomt App ID.
62 | * That was created here: https://www.stomt.com/dev/my-apps
63 | * @param AppID - Stomt APP ID
64 | */
65 | void SetAppId(FString NewAppId);
66 |
67 | FString GetAppId();
68 |
69 | /**
70 | * Returns the Target-Name that can be displayed.
71 | * Only call this after a target was requested.
72 | */
73 | FString GetTargetName();
74 |
75 | /**
76 | * Sets a Stomt Target
77 | * @param TargetID - ID of Stomt Target
78 | */
79 | void SetTargetId(FString NewTargetId);
80 |
81 | FString GetTargetId();
82 |
83 | /**
84 | * Sets the URL for the target image.
85 | * @param URL - Target-Image URL
86 | */
87 | void SetImageUrl(FString NewImageUrl);
88 |
89 | FString GetImageUrl();
90 |
91 | void SetStomtToSend(UStomt* Stomt);
92 |
93 | /**
94 | * Gets the Request object that contains Request/response information.
95 | */
96 | UStomtRestRequest* GetRequest();
97 |
98 | //////////////////////////////////////////////////////////////////////////
99 | // Stomt File Access
100 |
101 | /**
102 | * Loads an Log file from disk.
103 | * @param LogFileName - Log File Name.
104 | */
105 | FString ReadLogFile(FString LogFileName);
106 |
107 | //////////////////////////////////////////////////////////////////////////
108 | // Network
109 |
110 | UFUNCTION()
111 | void OnSendStomtRequestResponse(UStomtRestRequest * Request);
112 |
113 | UStomtRestRequest* SendLoginRequest(FString UserName, FString Password);
114 |
115 | UFUNCTION()
116 | void OnLoginRequestResponse(UStomtRestRequest * Request);
117 |
118 | UStomtRestRequest* RequestSession();
119 |
120 | UFUNCTION()
121 | void OnRequestSessionResponse(UStomtRestRequest * Request);
122 |
123 | /**
124 | * Sends an REST Request for a stomt target.
125 | */
126 | UFUNCTION(BlueprintCallable, Category = "Stomt API")
127 | UStomtRestRequest* RequestTargetByAppId();
128 |
129 | /**
130 | * Sends an REST Request for a stomt target.
131 | * To receive the respose it is necessary to add a event delegate function.
132 | * For example: api->GetRequest()->OnRequestComplete.AddDynamic(this, &UStomtPluginWidget::OnLoginRequestResponse).
133 | * @param TargetID - ID of the requested stomt target.
134 | */
135 | UFUNCTION(BlueprintCallable, Category = "Stomt API")
136 | UStomtRestRequest* RequestTarget(FString TargetId);
137 |
138 | UFUNCTION()
139 | void OnRequestTargetResponse(UStomtRestRequest * Request);
140 |
141 | /**
142 | * Sends the LogFileData to stomt.com server.
143 | */
144 | void SendLogFile(FString LogFileData, FString LogFileName);
145 |
146 | UFUNCTION()
147 | void OnSendLogFileResponse(UStomtRestRequest * Request);
148 |
149 | /**
150 | * Sends the Image to stomt.com server.
151 | */
152 | void SendImageFile(FString ImageFileDataBase64);
153 |
154 | UFUNCTION()
155 | void OnSendImageFileResponse(UStomtRestRequest * Request);
156 |
157 | void SendSubscription(FString EMail);
158 |
159 | void SendSubscription(FString EMailOrNumber, bool bUseEmail);
160 |
161 | UFUNCTION()
162 | void OnSendEMailResponse(UStomtRestRequest * Request);
163 |
164 | void SendLogoutRequest();
165 |
166 | UFUNCTION()
167 | void OnSendLogoutResponse(UStomtRestRequest * Request);
168 |
169 | //////////////////////////////////////////////////////////////////////////
170 | // Track SDK Usage
171 |
172 | UFUNCTION(BlueprintCallable, Category = "Stomt Track")
173 | void SendTrack(UStomtTrack* NewTrack);
174 |
175 |
176 | //////////////////////////////////////////////////////////////////////////
177 | // Screenshot
178 |
179 | UFUNCTION()
180 | FString ReadScreenshotAsBase64();
181 |
182 | //////////////////////////////////////////////////////////////////////////
183 | // Request callbacks
184 |
185 | public:
186 | /** Event occured when the Request has been completed */
187 | UPROPERTY(BlueprintAssignable, Category = "Stomt|Event")
188 | FOnTargetRequestComplete OnSessionRequestComplete;
189 |
190 | /** Event occured when the Request has been completed */
191 | UPROPERTY(BlueprintAssignable, Category = "Stomt|Event")
192 | FOnTargetRequestComplete OnTargetRequestComplete;
193 |
194 | /** Event occured when the Request has been completed */
195 | UPROPERTY(BlueprintAssignable, Category = "Stomt|Event")
196 | FOnLoginRequestComplete OnLoginRequestComplete;
197 |
198 | /** Event occured when the Request has been completed */
199 | //UPROPERTY(BlueprintAssignable, Category = "Stomt|Event")
200 | //FOnRequestComplete OnRequestComplete; // ToDo Trigger this
201 |
202 | /** Event occured when the Request wasn't successfull */
203 | UPROPERTY(BlueprintAssignable, Category = "Stomt|Event")
204 | FOnRequestFailed OnRequestFailed;
205 |
206 | UFUNCTION()
207 | void OnARequestFailed(UStomtRestRequest* Request);
208 |
209 | UFUNCTION(BlueprintCallable, Category = "Stomt API")
210 | bool IsConnected();
211 |
212 | UFUNCTION(BlueprintCallable, Category = "Stomt API")
213 | void ConnectionTest();
214 |
215 | //////////////////////////////////////////////////////////////////////////
216 | // Data
217 | public:
218 |
219 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stomt API")
220 | UStomtConfig* Config;
221 |
222 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stomt API")
223 | UStomtTrack* Track;
224 |
225 | UStomt* StomtToSend;
226 |
227 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stomt API")
228 | FString ImageUploadName;
229 |
230 | FString ErrorLogFileUid;
231 |
232 | FString DefaultScreenshotName;
233 |
234 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Stomt API")
235 | bool bUseImageUpload;
236 |
237 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Stomt API")
238 | bool bUseDefaultLabels;
239 |
240 | bool bIsLogUploadComplete;
241 |
242 | bool bIsImageUploadComplete;
243 |
244 | bool bLoginRequestWasSend;
245 |
246 | bool bEMailFlagWasSend;
247 |
248 | bool bLogFileWasSend;
249 |
250 | bool bNetworkError;
251 |
252 | FString RestUrl;
253 |
254 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Stomt API")
255 | FString StomtUrl;
256 |
257 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Stomt API")
258 | FString TargetName;
259 |
260 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Stomt API")
261 | FString TargetId;
262 |
263 | FString AppId;
264 |
265 | FString ImageUrl;
266 |
267 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Stomt API")
268 | int StomtsCreatedByUser;
269 |
270 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Stomt API")
271 | int StomtsReceivedByTarget;
272 |
273 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Stomt API")
274 | FString UserId;
275 |
276 | //////////////////////////////////////////////////////////////////////////
277 | // Multi-Language
278 |
279 | public:
280 | UFUNCTION(BlueprintCallable, Category = "Stomt API")
281 | UStomtRestJsonObject* LoadLanguageFile();
282 |
283 | UFUNCTION(BlueprintCallable, Category = "Stomt API")
284 | FString GetLangText(FString Text);
285 |
286 | UFUNCTION(BlueprintCallable, Category = "Stomt API")
287 | FString GetCurrentLanguage();
288 |
289 | UFUNCTION(BlueprintCallable, Category = "Stomt API")
290 | bool SetCurrentLanguage(FString newLanguage);
291 |
292 | private:
293 | FString GetSystemLanguage();
294 |
295 | FString LoadLanguageFileContent();
296 |
297 | UPROPERTY()
298 | UStomtRestJsonObject* Languages;
299 |
300 | UPROPERTY()
301 | FString CurrentLanguage;
302 |
303 | //////////////////////////////////////////////////////////////////////////
304 | // Helper Functions
305 |
306 | public:
307 | UFUNCTION(BlueprintCallable, Category = "Stomt API")
308 | bool IsEmailCorrect(FString Email);
309 |
310 | UFUNCTION(BlueprintCallable, Category = "Stomt API")
311 | bool DoesScreenshotFileExist();
312 |
313 | UFUNCTION(BlueprintCallable, Category = "Stomt API")
314 | void UseScreenshotUpload(bool bUseUpload);
315 |
316 | void AddCustomKeyValuePair(FString key, FString value);
317 |
318 | void HandleOfflineStomts();
319 |
320 | UFUNCTION(BlueprintCallable, Category = "Stomt API")
321 | void SendOfflineStomts();
322 |
323 | private:
324 | bool WriteFile(FString TextToSave, FString FileName, FString SaveDirectory, bool bAllowOverwriting);
325 |
326 | bool ReadFile(FString& Result, FString FileName, FString SaveDirectory);
327 |
328 | TArray ReadBinaryFile(FString FilePath);
329 |
330 | UStomtRestRequest* SetupNewRequest(StomtEnumRequestVerb::Type Verb);
331 |
332 | void AddAccesstokenToRequest(UStomtRestRequest* Request);
333 |
334 | UFUNCTION()
335 | void ParseAccessTokenFromResponse(UStomtRestRequest * Request);
336 |
337 | TArray> CustomKeyValuePairs;
338 | };
339 |
--------------------------------------------------------------------------------
/Source/StomtPlugin/Public/StomtConfig.h:
--------------------------------------------------------------------------------
1 | // Copyright 2018 STOMT GmbH. All Rights Reserved.
2 | #pragma once
3 | #include "StomtJsonObject.h"
4 | #include "Stomt.h"
5 | #include "StomtPluginPrivatePCH.h"
6 | #include "StomtRestRequest.h"
7 | #include "StomtConfig.generated.h"
8 |
9 |
10 | DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnConfigUpdated, class UStomtConfig*, Config);
11 |
12 | UCLASS()
13 | class UStomtConfig : public UObject
14 | {
15 | GENERATED_BODY()
16 |
17 | public:
18 |
19 | static UStomtConfig* ConstructStomtConfig();
20 |
21 | UStomtConfig();
22 |
23 | ~UStomtConfig();
24 | //////////////////////////////////////////////////////////////////////////
25 | // Public
26 |
27 | /**
28 | * checks if a config file exists, creates one or reads it
29 | **/
30 | UFUNCTION(BlueprintCallable, Category = "Stomt Widget Plugin")
31 | void Load();
32 |
33 | /**
34 | * deletes to current config file
35 | **/
36 | void Delete();
37 |
38 | UFUNCTION(BlueprintCallable, Category = "Stomt Widget Plugin")
39 | FString GetAccessToken();
40 |
41 | void SetAccessToken(FString NewAccessToken);
42 |
43 | UFUNCTION(BlueprintCallable, Category = "Stomt Widget Plugin")
44 | bool GetSubscribed();
45 |
46 | void SetSubscribed(bool bNewSubscribed);
47 |
48 | UFUNCTION(BlueprintCallable, Category = "Stomt Widget Plugin")
49 | bool GetLoggedIn();
50 |
51 | void SetLoggedIn(bool bNewLoggedIn);
52 |
53 | UFUNCTION(BlueprintCallable, Category = "Stomt Widget Plugin")
54 | bool GetAcceptScreenshotUpload();
55 |
56 | UFUNCTION(BlueprintCallable, Category = "Stomt Widget Plugin")
57 | void SetAcceptScreenshotUpload(bool bNewAcceptScreenshotUpload);
58 |
59 | UFUNCTION(BlueprintCallable, Category = "Stomt Widget Plugin")
60 | bool GetAcceptLogUpload();
61 |
62 | UFUNCTION(BlueprintCallable, Category = "Stomt Widget Plugin")
63 | void SetAcceptLogUpload(bool bNewAcceptLogUpload);
64 |
65 | UPROPERTY(BlueprintAssignable, Category = "Stomt|Event")
66 | FOnConfigUpdated OnConfigUpdated;
67 |
68 | UFUNCTION(BlueprintCallable, Category = "Stomt Widget Plugin")
69 | TArray GetStomtsAsJson();
70 |
71 | UFUNCTION(BlueprintCallable, Category = "Stomt Widget Plugin")
72 | TArray GetStomts();
73 |
74 | UFUNCTION(BlueprintCallable, Category = "Stomt Widget Plugin")
75 | bool AddStomt(UStomt* NewStomt);
76 |
77 | /**
78 | * Clears the stomt array in /stomt/stomt.conf.json
79 | */
80 | bool ClearStomts();
81 |
82 | private:
83 |
84 | //////////////////////////////////////////////////////////////////////////
85 | // Read Config
86 |
87 | /**
88 | * Loads the access token from disk.
89 | */
90 | FString ReadStomtConf(FString FieldName);
91 |
92 | /**
93 | * Loads the flag from disk.
94 | */
95 | bool ReadFlag(FString FlagName);
96 |
97 | /**
98 | * Loads the access token from disk.
99 | */
100 | UStomtRestJsonObject* ReadStomtConfAsJson();
101 |
102 | /**
103 | * Loads the access token from disk.
104 | */
105 | FString ReadAccessToken();
106 |
107 | //////////////////////////////////////////////////////////////////////////
108 | // Write Config
109 |
110 | /**
111 | * Saves the access token in /stomt/stomt.conf.json
112 | */
113 | bool SaveAccessToken(FString NewAccessToken);
114 |
115 | /**
116 | * Saves the a value in /stomt/stomt.conf.json
117 | */
118 | bool SaveValueToStomtConf(FString FieldName, FString FieldValue);
119 |
120 | /**
121 | * Saves the a stomt in /stomt/stomt.conf.json
122 | */
123 | bool SaveStomtToConf(UStomt& NewStomt);
124 |
125 | /**
126 | * Saves the flag in /stomt/stomt.conf.json
127 | */
128 | bool SaveFlag(FString FlagName, bool bFlagState);
129 |
130 | /**
131 | * Loads the access token from disk.
132 | */
133 | bool WriteStomtConfAsJson(UStomtRestJsonObject* StomtConf);
134 |
135 | /**
136 | * Delete stomt.conf.json
137 | */
138 | void DeleteStomtConf();
139 |
140 | /**
141 | * Loads an Log file from disk.
142 | * @param LogFileName - Log File Name.
143 | */
144 | FString ReadLogFile(FString LogFileName);
145 |
146 | bool WriteFile(FString TextToSave, FString FileName, FString SaveDirectory, bool AllowOverwriting);
147 |
148 | bool ReadFile(FString& Result, FString FileName, FString SaveDirectory);
149 |
150 | //////////////////////////////////////////////////////////////////////////
151 | // Data
152 |
153 | bool bSubscribed;
154 | bool bLoggedIn;
155 | bool bAcceptLogUpload;
156 | bool bAcceptScreenshotUpload;
157 |
158 | FString SubscribedFieldName;
159 | FString LoggedInFieldName;
160 | FString AccessTokenFieldName;
161 | FString StomtsFieldName;
162 | FString LogUploadFieldName;
163 | FString ScreenshotUploadFieldName;
164 |
165 | FString AccessToken;
166 | FString ConfigFolder;
167 | FString ConfigName;
168 |
169 | UPROPERTY()
170 | TArray Stomts;
171 | };
172 |
--------------------------------------------------------------------------------
/Source/StomtPlugin/Public/StomtJsonObject.h:
--------------------------------------------------------------------------------
1 | // Copyright 2018 STOMT GmbH. All Rights Reserved.
2 | #pragma once
3 |
4 | #include "StomtJsonValue.h"
5 | #include "StomtJsonObject.generated.h"
6 |
7 | /**
8 | * Blueprintable FJsonObject wrapper
9 | */
10 | UCLASS()
11 | class UStomtRestJsonObject : public UObject
12 | {
13 | GENERATED_BODY()
14 |
15 | public:
16 |
17 | UStomtRestJsonObject();
18 |
19 | /** Create new Json object */
20 | UFUNCTION(BlueprintPure, meta = (DisplayName = "Construct Json Object", HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"), Category = "Stomt|Json")
21 | static UStomtRestJsonObject* ConstructJsonObject(UObject* WorldContextObject);
22 |
23 | /** Reset all internal data */
24 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
25 | void Reset();
26 |
27 | /** Get the root Json object */
28 | TSharedPtr& GetRootObject();
29 |
30 | /** Set the root Json object */
31 | void SetRootObject(TSharedPtr& JsonObject);
32 |
33 |
34 | // //////////////////////////////////////////////////////////////////////////
35 | // // Serialization
36 |
37 | /** Serialize Json to string (formatted with line breaks) */
38 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
39 | FString EncodeJson() const;
40 |
41 | /** Serialize Json to string (signel string without line breaks) */
42 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
43 | FString EncodeJsonToSingleString() const;
44 |
45 | /** Construct Json object from string */
46 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
47 | bool DecodeJson(const FString& JsonString);
48 |
49 |
50 | // //////////////////////////////////////////////////////////////////////////
51 | // // FJsonObject API
52 | //
53 | /** Returns a list of field names that exist in the object */
54 | UFUNCTION(BlueprintPure, Category = "Stomt|Json")
55 | TArray GetFieldNames();
56 |
57 | /** Checks to see if the FieldName exists in the object */
58 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
59 | bool HasField(const FString& FieldName) const;
60 |
61 | /** Remove field named FieldName */
62 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
63 | void RemoveField(const FString& FieldName);
64 |
65 | /** Get the field named FieldName as a JsonValue */
66 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
67 | UStomtJsonValue* GetField(const FString& FieldName) const;
68 |
69 | /** Add a field named FieldName with a Value */
70 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
71 | void SetField(const FString& FieldName, UStomtJsonValue* JsonValue);
72 |
73 | /** Get the field named FieldName as a Json Array */
74 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
75 | TArray GetArrayField(const FString& FieldName);
76 |
77 | /** Set an ObjectField named FieldName and value of Json Array */
78 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
79 | void SetArrayField(const FString& FieldName, const TArray& InArray);
80 |
81 | /** Adds all of the fields from one json object to this one */
82 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
83 | void MergeJsonObject(UStomtRestJsonObject* InJsonObject, bool Overwrite);
84 |
85 |
86 | // //////////////////////////////////////////////////////////////////////////
87 | // // FJsonObject API Helpers (easy to use with simple Json objects)
88 |
89 | /** Get the field named FieldName as a number. Ensures that the field is present and is of type Json number.
90 | * Attn.!! float used instead of double to make the function blueprintable! */
91 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
92 | float GetNumberField(const FString& FieldName) const;
93 |
94 | /** Add a field named FieldName with Number as value
95 | * Attn.!! float used instead of double to make the function blueprintable! */
96 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
97 | void SetNumberField(const FString& FieldName, float Number);
98 |
99 | /** Get the field named FieldName as a string. */
100 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
101 | FString GetStringField(const FString& FieldName) const;
102 |
103 | /** add a field named fieldname with value of stringvalue */
104 | UFUNCTION(BlueprintCallable, category = "Stomt|Json")
105 | void SetStringField(const FString& Fieldname, const FString& stringvalue);
106 |
107 | /** Get the field named FieldName as a boolean. */
108 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
109 | bool GetBoolField(const FString& FieldName) const;
110 |
111 | /** Set a boolean field named FieldName and value of InValue */
112 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
113 | void SetBoolField(const FString& FieldName, bool InValue);
114 |
115 | /** Get the field named FieldName as a Json object. */
116 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
117 | UStomtRestJsonObject* GetObjectField(const FString& FieldName) const;
118 |
119 | /** Set an ObjectField named FieldName and value of JsonObject */
120 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
121 | void SetObjectField(const FString& FieldName, UStomtRestJsonObject* JsonObject);
122 |
123 | //
124 | // //////////////////////////////////////////////////////////////////////////
125 | // // Array fields helpers (uniform arrays)
126 |
127 | /** Get the field named FieldName as a Number Array. Use it only if you're sure that array is uniform!
128 | * Attn.!! float used instead of double to make the function blueprintable! */
129 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
130 | TArray GetNumberArrayField(const FString& FieldName);
131 |
132 | /** Set an ObjectField named FieldName and value of Number Array
133 | * Attn.!! float used instead of double to make the function blueprintable! */
134 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
135 | void SetNumberArrayField(const FString& FieldName, const TArray& NumberArray);
136 |
137 | /** Get the field named FieldName as a String Array. Use it only if you're sure that array is uniform! */
138 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
139 | TArray GetStringArrayField(const FString& FieldName);
140 |
141 | /** Set an ObjectField named FieldName and value of String Array */
142 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
143 | void SetStringArrayField(const FString& FieldName, const TArray& StringArray);
144 |
145 | /** Get the field named FieldName as a Bool Array. Use it only if you're sure that array is uniform! */
146 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
147 | TArray GetBoolArrayField(const FString& FieldName);
148 |
149 | /** Set an ObjectField named FieldName and value of Bool Array */
150 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
151 | void SetBoolArrayField(const FString& FieldName, const TArray& BoolArray);
152 |
153 | /** Get the field named FieldName as an Object Array. Use it only if you're sure that array is uniform! */
154 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
155 | TArray GetObjectArrayField(const FString& FieldName);
156 |
157 | /** Set an ObjectField named FieldName and value of Ob Array */
158 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
159 | void SetObjectArrayField(const FString& FieldName, const TArray& ObjectArray);
160 |
161 |
162 | // //////////////////////////////////////////////////////////////////////////
163 | // // Data
164 |
165 | private:
166 | /** Internal JSON data */
167 | TSharedPtr JsonObj;
168 |
169 | };
170 |
--------------------------------------------------------------------------------
/Source/StomtPlugin/Public/StomtJsonValue.h:
--------------------------------------------------------------------------------
1 | // Copyright 2018 STOMT GmbH. All Rights Reserved.
2 | #pragma once
3 |
4 | #include "StomtPluginPrivatePCH.h"
5 | #include "StomtJsonValue.generated.h"
6 |
7 | /**
8 | * Represents all the types a Json Value can be.
9 | */
10 | UENUM(BlueprintType)
11 | namespace StomtEnumJson
12 | {
13 | enum Type
14 | {
15 | None,
16 | Null,
17 | String,
18 | Number,
19 | Boolean,
20 | Array,
21 | Object,
22 | };
23 | }
24 |
25 | /**
26 | * Blueprintable FJsonValue wrapper
27 | */
28 | UCLASS(BlueprintType, Blueprintable)
29 | class UStomtJsonValue : public UObject
30 | {
31 | GENERATED_BODY()
32 |
33 | public:
34 |
35 | /** Create new Json Number value
36 | * Attn.!! float used instead of double to make the function blueprintable! */
37 | UFUNCTION(BlueprintPure, meta = (DisplayName = "Construct Json Number Value", HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"), Category = "Stomt|Json")
38 | static UStomtJsonValue* ConstructJsonValueNumber(UObject* WorldContextObject, float Number);
39 |
40 | /** Create new Json String value */
41 | UFUNCTION(BlueprintPure, meta = (DisplayName = "Construct Json String Value", HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"), Category = "Stomt|Json")
42 | static UStomtJsonValue* ConstructJsonValueString(UObject* WorldContextObject, const FString& StringValue);
43 |
44 | /** Create new Json Bool value */
45 | UFUNCTION(BlueprintPure, meta = (DisplayName = "Construct Json Bool Value", HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"), Category = "Stomt|Json")
46 | static UStomtJsonValue* ConstructJsonValueBool(UObject* WorldContextObject, bool InValue);
47 |
48 | /** Create new Json Array value */
49 | UFUNCTION(BlueprintPure, meta = (DisplayName = "Construct Json Array Value", HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"), Category = "Stomt|Json")
50 | static UStomtJsonValue* ConstructJsonValueArray(UObject* WorldContextObject, const TArray& InArray);
51 |
52 | /** Create new Json value from FJsonValue (to be used from StomtJsonObject) */
53 | static UStomtJsonValue* ConstructJsonValue(UObject* WorldContextObject, const TSharedPtr& InValue);
54 |
55 | /** Get the root Json value */
56 | TSharedPtr& GetRootValue();
57 |
58 | /** Set the root Json value */
59 | void SetRootValue(TSharedPtr& JsonValue);
60 |
61 |
62 | //////////////////////////////////////////////////////////////////////////
63 | // FJsonValue API
64 |
65 | /** Get type of Json value (Enum) */
66 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
67 | StomtEnumJson::Type GetType() const;
68 |
69 | /** Get type of Json value (String) */
70 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
71 | FString GetTypeString() const;
72 |
73 | /** Returns true if this value is a 'null' */
74 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
75 | bool IsNull() const;
76 |
77 | /** Returns this value as a double, throwing an error if this is not an Json Number
78 | * Attn.!! float used instead of double to make the function blueprintable! */
79 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
80 | float AsNumber() const;
81 |
82 | /** Returns this value as a number, throwing an error if this is not an Json String */
83 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
84 | FString AsString() const;
85 |
86 | /** Returns this value as a boolean, throwing an error if this is not an Json Bool */
87 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
88 | bool AsBool() const;
89 |
90 | /** Returns this value as an array, throwing an error if this is not an Json Array */
91 | UFUNCTION(BlueprintCallable, Category = "Stomt|Json")
92 | TArray AsArray() const;
93 |
94 | //////////////////////////////////////////////////////////////////////////
95 | // Data
96 |
97 | private:
98 |
99 | /** Internal JSON data */
100 | TSharedPtr JsonVal;
101 |
102 |
103 | //////////////////////////////////////////////////////////////////////////
104 | // Helpers
105 |
106 | protected:
107 |
108 | /** Simple error logger */
109 | void ErrorMessage(const FString& InType) const;
110 |
111 | };
112 |
--------------------------------------------------------------------------------
/Source/StomtPlugin/Public/StomtLabel.h:
--------------------------------------------------------------------------------
1 | // Copyright 2018 STOMT GmbH. All Rights Reserved.
2 | #pragma once
3 |
4 | #include "StomtPluginPrivatePCH.h"
5 | #include "StomtLabel.generated.h"
6 |
7 | UCLASS()
8 | class UStomtLabel : public UObject
9 | {
10 | GENERATED_BODY()
11 |
12 | public:
13 |
14 | //////////////////////////////////////////////////////////////////////////
15 | // Construction
16 |
17 | UStomtLabel();
18 | //~UStomtLabel();
19 |
20 | static UStomtLabel* ConstructLabel(FString NewName);
21 |
22 |
23 | //////////////////////////////////////////////////////////////////////////
24 | // Data accessors
25 |
26 | void SetName(FString NewName);
27 | void SetColor(FString NewColor);
28 | void SetIsPublic(bool bNewIsPublic);
29 | void SetAsTargetOwner(bool bNewAsTargetOwner);
30 |
31 | FString GetName();
32 | FString GetColor();
33 | bool GetIsPublic();
34 | bool GetAsTargetOwner();
35 |
36 | private:
37 |
38 | //////////////////////////////////////////////////////////////////////////
39 | // Data
40 |
41 | UPROPERTY()
42 | FString Name;
43 | UPROPERTY()
44 | FString Color;
45 | UPROPERTY()
46 | bool bIsPublic;
47 | UPROPERTY()
48 | bool bAsTargetOwner;
49 |
50 | };
51 |
52 |
--------------------------------------------------------------------------------
/Source/StomtPlugin/Public/StomtPlugin.h:
--------------------------------------------------------------------------------
1 | // Copyright 2018 STOMT GmbH. All Rights Reserved.
2 | #pragma once
3 |
4 | class StomtPlugin : public IModuleInterface
5 | {
6 |
7 | public:
8 |
9 | /**
10 | * Singleton-like access to this module's interface. This is just for convenience!
11 | * Beware of calling this during the shutdown phase, though. Your module might have been unloaded already.
12 | *
13 | * @return Returns singleton instance, loading the module on demand if needed
14 | */
15 | static inline StomtPlugin& Get()
16 | {
17 | return FModuleManager::LoadModuleChecked< StomtPlugin >("StomtPlugin");
18 | }
19 |
20 | /**
21 | * Checks to see if this module is loaded and ready. It is only valid to call Get() if IsAvailable() returns true.
22 | *
23 | * @return True if the module is loaded and ready to use
24 | */
25 | static inline bool IsAvailable()
26 | {
27 | return FModuleManager::Get().IsModuleLoaded("StomtPlugin");
28 | }
29 |
30 | };
31 |
--------------------------------------------------------------------------------
/Source/StomtPlugin/Public/StomtPluginPrivatePCH.h:
--------------------------------------------------------------------------------
1 | // Copyright 2018 STOMT GmbH. All Rights Reserved.
2 | #pragma once
3 |
4 | #include "CoreUObject.h"
5 | #include "Engine.h"
6 |
7 | #include "Http.h"
8 | #include "Json.h"
9 |
10 | #include "LatentActions.h"
11 | #include "Core.h"
12 | #include "Engine.h"
13 |
14 | DECLARE_LOG_CATEGORY_EXTERN(StomtLog, Log, All);
15 |
16 | //Logging during plugin startup
17 | DECLARE_LOG_CATEGORY_EXTERN(StomtInit, Log, All);
18 |
19 | //Logging during network communication
20 | DECLARE_LOG_CATEGORY_EXTERN(StomtNetwork, Log, All);
21 |
22 | //Logging during file access
23 | DECLARE_LOG_CATEGORY_EXTERN(StomtFileAccess, Log, All);
24 | #include "StomtPlugin.h"
25 |
--------------------------------------------------------------------------------
/Source/StomtPlugin/Public/StomtPluginWidget.h:
--------------------------------------------------------------------------------
1 | // Copyright 2018 STOMT GmbH. All Rights Reserved.
2 | #pragma once
3 |
4 | #include "Runtime/UMG/Public/UMG.h"
5 | #include "Runtime/UMG/Public/UMGStyle.h"
6 | #include "Runtime/UMG/Public/Slate/SObjectWidget.h"
7 | #include "Runtime/UMG/Public/IUMGModule.h"
8 | #include "Runtime/UMG/Public/Blueprint/UserWidget.h"
9 |
10 | #include "Blueprint/UserWidget.h"
11 |
12 | #include "StomtRestRequest.h"
13 | #include "Stomt.h"
14 | #include "StomtAPI.h"
15 | #include "StomtConfig.h"
16 |
17 | #include "StomtPluginWidget.generated.h"
18 |
19 | UCLASS()
20 | class UStomtPluginWidget : public UUserWidget
21 | {
22 | GENERATED_BODY()
23 |
24 | public:
25 |
26 | ~UStomtPluginWidget();
27 |
28 | /**
29 | * Stomt content-text from the UI textbox.
30 | */
31 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stomt Widget Plugin")
32 | FString Message;
33 |
34 | /**
35 | * Stomt details-text from the UI textbox.
36 | */
37 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stomt Widget Plugin")
38 | FString Details;
39 |
40 | /**
41 | * EMail from the UI EMail layer.
42 | */
43 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stomt Widget Plugin")
44 | FString EMail;
45 |
46 | /**
47 | * UserName from the UI Login layer.
48 | */
49 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stomt Widget Plugin")
50 | FString UserName;
51 |
52 | /**
53 | * UserPassword from the UI Login layer.
54 | */
55 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stomt Widget Plugin")
56 | FString UserPassword;
57 |
58 | /**
59 | * Target-name that will be shown in the widget.
60 | */
61 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stomt Widget Plugin")
62 | FString TargetName;
63 |
64 | /**
65 | * Target-image URL
66 | */
67 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stomt Widget Plugin")
68 | FString ImageUrl;
69 |
70 | /**
71 | * STOMT API.
72 | */
73 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stomt Widget Plugin")
74 | UStomtAPI* Api;
75 |
76 | /**
77 | * STOMT Config.
78 | */
79 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stomt Widget Plugin")
80 | UStomtConfig* Config;
81 |
82 | /**
83 | * Whether the E-Mail variable is a phone number.
84 | */
85 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stomt Widget Plugin")
86 | bool bUsePhoneNumber;
87 |
88 | /**
89 | * Whether the stomt is not positive (a wish).
90 | */
91 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stomt Widget Plugin")
92 | bool bIsWish;
93 |
94 | /**
95 | * Whether a screenshot should be appended. (not implemented)
96 | */
97 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stomt Widget Plugin")
98 | bool bIsScreenshotSelected;
99 |
100 | /**
101 | * Whether the user mail is already known.
102 | */
103 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stomt Widget Plugin")
104 | bool bIsEMailAlreadyKnown;
105 |
106 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stomt Widget Plugin")
107 | bool bIsUserLoggedIn;
108 |
109 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stomt Widget Plugin")
110 | bool bUploadLogs;
111 |
112 | /**
113 | * Error-Code whether the user login worked. (0: OK, 403: wrong password, 404: account does not exist. )
114 | */
115 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stomt Widget Plugin")
116 | int LoginErrorCode;
117 |
118 | /**
119 | * The labels which will be appended to the stomt.
120 | */
121 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stomt Widget Plugin")
122 | TArray Labels;
123 |
124 | /**
125 | * Event when text inside the widget changed.
126 | * @param text - Current text from the widget-textbox
127 | */
128 | UFUNCTION(BlueprintCallable, Category = "Stomt Widget Plugin")
129 | void OnMessageChanged(FString text);
130 |
131 | /**
132 | * Event when details text of the widget is committed.
133 | * @param text - Current details text from the widget-textbox
134 | */
135 | UFUNCTION(BlueprintCallable, Category = "Stomt Widget Plugin")
136 | void OnDetailsCommitted(FString text);
137 |
138 | /**
139 | * Once the user sends off the stomt.
140 | */
141 | UFUNCTION(BlueprintCallable, Category = "Stomt Widget Plugin")
142 | void OnSubmit();
143 |
144 | /**
145 | * Once the user finishes all layers.
146 | */
147 | UFUNCTION(BlueprintCallable, Category = "Stomt Widget Plugin")
148 | void OnSubmitLastLayer();
149 |
150 | /**
151 | * Once the user finishes the login.
152 | * @return Wether the login Request was send.
153 | */
154 | UFUNCTION(BlueprintCallable, Category = "Stomt Widget Plugin")
155 | bool OnSubmitLogin();
156 |
157 | /**
158 | * Once the user finishes the email input.
159 | */
160 | UFUNCTION(BlueprintCallable, Category = "Stomt Widget Plugin")
161 | void OnSubmitEMail();
162 |
163 | /**
164 | * Once the user logs out.
165 | */
166 | UFUNCTION(BlueprintCallable, Category = "Stomt Widget Plugin")
167 | void OnLogout();
168 |
169 | /**
170 | * Called at the widget startup to initialize variables.
171 | * @param TargetID - Stomt target-id
172 | * @param RestURL - Stomt REST-API URL
173 | * @param AppID - Stomt application-ID
174 | */
175 | UFUNCTION(BlueprintCallable, Category = "Stomt Widget Plugin")
176 | void OnConstruction(FString AppID);
177 |
178 | /**
179 | * Event called after the stomt server responded.
180 | * @param CurrentRequest - Stomt Request that carries the response information.
181 | */
182 | UFUNCTION(BlueprintCallable, Category = "Stomt Widget Plugin")
183 | void OnLoginResponse(UStomtRestRequest* CurrentRequest);
184 |
185 | UFUNCTION()
186 | void OnTargetResponse(UStomtRestRequest * TargetRequest);
187 |
188 | UFUNCTION(BlueprintCallable, Category = "Stomt Widget Plugin")
189 | FString AppendStomtURLParams(FString url, FString utm_content);
190 |
191 | // Not ready yet.
192 | UFUNCTION(BlueprintCallable, Category = "Stomt Widget Plugin")
193 | void UploadScreenshot();
194 |
195 | private:
196 |
197 | UPROPERTY()
198 | UStomt* Stomt;
199 |
200 | };
201 |
--------------------------------------------------------------------------------
/Source/StomtPlugin/Public/StomtRestRequest.h:
--------------------------------------------------------------------------------
1 | // Copyright 2018 STOMT GmbH. All Rights Reserved.
2 | #pragma once
3 |
4 | #include "StomtPluginPrivatePCH.h"
5 | #include "StomtJsonObject.h"
6 | #include "StomtRestRequest.generated.h"
7 |
8 | /**
9 | * @author Original latent action class by https://github.com/unktomi
10 | */
11 | template class StomtLatentAction : public FPendingLatentAction
12 | {
13 | public:
14 |
15 | virtual void Call(const T &Value)
16 | {
17 | Result = Value;
18 | Called = true;
19 | }
20 |
21 | void operator()(const T &Value)
22 | {
23 | Call(Value);
24 | }
25 |
26 | void Cancel();
27 |
28 | StomtLatentAction(FWeakObjectPtr RequestObj, T& ResultParam, const FLatentActionInfo& LatentInfo) :
29 | Called(false),
30 | Request(RequestObj),
31 | ExecutionFunction(LatentInfo.ExecutionFunction),
32 | OutputLink(LatentInfo.Linkage),
33 | CallbackTarget(LatentInfo.CallbackTarget),
34 | Result(ResultParam)
35 | {
36 | }
37 |
38 | virtual void UpdateOperation(FLatentResponse& Response) override
39 | {
40 | Response.FinishAndTriggerIf(Called, ExecutionFunction, OutputLink, CallbackTarget);
41 | }
42 |
43 | virtual void NotifyObjectDestroyed()
44 | {
45 | Cancel();
46 | }
47 |
48 | virtual void NotifyActionAborted()
49 | {
50 | Cancel();
51 | }
52 |
53 | private:
54 | bool Called;
55 | FWeakObjectPtr Request;
56 |
57 | public:
58 | const FName ExecutionFunction;
59 | const int32 OutputLink;
60 | const FWeakObjectPtr CallbackTarget;
61 | T &Result;
62 |
63 | };
64 |
65 | /** Verb (GET, PUT, POST) */
66 | UENUM(BlueprintType)
67 | namespace StomtEnumRequestVerb
68 | {
69 | enum Type
70 | {
71 | GET,
72 | POST,
73 | PUT,
74 | DEL UMETA(DisplayName = "DELETE"),
75 | };
76 | }
77 |
78 | /** Generate a delegates for callback events */
79 | DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnRequestComplete, class UStomtRestRequest*, Request);
80 | DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnRequestFail, class UStomtRestRequest*, Request);
81 |
82 |
83 | UCLASS()
84 | class UStomtRestRequest : public UObject
85 | {
86 | GENERATED_BODY()
87 |
88 | public:
89 | //////////////////////////////////////////////////////////////////////////
90 | // Construction
91 |
92 | UStomtRestRequest();
93 | ~UStomtRestRequest();
94 |
95 | static UStomtRestRequest* ConstructRequest();
96 |
97 | /** Set verb to the Request */
98 | void SetVerb(StomtEnumRequestVerb::Type Verb);
99 |
100 | /** Sets header info */
101 | void SetHeader(const FString &HeaderName, const FString &HeaderValue);
102 |
103 | void OnResponseReceived(
104 | FHttpRequestPtr Request,
105 | FHttpResponsePtr Response,
106 | bool bWasSuccessful);
107 |
108 | //////////////////////////////////////////////////////////////////////////
109 | // Destruction and reset
110 |
111 | /** Reset all internal saved data */
112 | void ResetData();
113 |
114 | /** Reset saved Request data */
115 | void ResetRequestData();
116 |
117 | /** Reset saved response data */
118 | void ResetResponseData();
119 |
120 | /** Cancel latent response waiting */
121 | void Cancel();
122 |
123 |
124 | //////////////////////////////////////////////////////////////////////////
125 | // JSON data accessors
126 |
127 | /** Get the Request Json object */
128 | UStomtRestJsonObject* GetRequestObject();
129 |
130 | /** Set the Request Json object */
131 | void SetRequestObject(UStomtRestJsonObject* JsonObject);
132 |
133 | /** Get the Response Json object */
134 | UStomtRestJsonObject* GetResponseObject();
135 |
136 | /** Set the Response Json object */
137 | void SetResponseObject(UStomtRestJsonObject* JsonObject);
138 |
139 |
140 | ///////////////////////////////////////////////////////////////////////////
141 | // Response data access
142 |
143 | /** Get the responce code of the last query */
144 | int32 GetResponseCode();
145 |
146 | /** Get value of desired response header */
147 | FString GetResponseHeader(const FString HeaderName);
148 |
149 | /** Get list of all response headers */
150 | TArray GetAllResponseHeaders();
151 |
152 |
153 | //////////////////////////////////////////////////////////////////////////
154 | // URL processing
155 |
156 | /** Open URL with current setup */
157 | virtual void ProcessUrl(const FString& Url);
158 |
159 |
160 | //////////////////////////////////////////////////////////////////////////
161 | // Request callbacks
162 |
163 | private:
164 | /** Internal bind function for the IHTTPRequest::OnProcessRequestCompleted() event */
165 | void OnProcessRequestComplete(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful);
166 |
167 | public:
168 | /** Event occured when the Request has been completed */
169 | UPROPERTY(BlueprintAssignable, Category = "Stomt|Event")
170 | FOnRequestComplete OnRequestComplete;
171 |
172 | /** Event occured when the Request wasn't successfull */
173 | UPROPERTY(BlueprintAssignable, Category = "Stomt|Event")
174 | FOnRequestFail OnRequestFail;
175 |
176 | //////////////////////////////////////////////////////////////////////////
177 | // Data
178 | public:
179 | /** Wether to use a static json string instead of JsonObjects */
180 | void UseStaticJsonString(bool bNewUseStaticJsonString);
181 |
182 | void UseRequestLogging(bool bNewRequestLogging);
183 |
184 | void SetStaticJsonString(FString JsonString);
185 |
186 | /** Request response stored as a string */
187 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "StomtRest|Response")
188 | FString ResponseContent;
189 |
190 | /** Is the response valid JSON? */
191 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "StomtRest|Response")
192 | bool bIsValidJsonResponse;
193 |
194 | protected:
195 |
196 | /** Wether to use a static json string instead of JsonObjects */
197 | bool bUseStaticJsonString;
198 |
199 | /** Wether to use a log output for the Request */
200 | bool bRequestLogging;
201 |
202 | /** Static json string that will be used instead of json objects */
203 | FString StaticJsonOutputString;
204 |
205 | /** Latent action helper */
206 | StomtLatentAction *ContinueAction;
207 |
208 | /** Internal Request data stored as JSON */
209 | UPROPERTY()
210 | UStomtRestJsonObject* RequestJsonObj;
211 |
212 | /** Response data stored as JSON */
213 | UPROPERTY()
214 | UStomtRestJsonObject* ResponseJsonObj;
215 |
216 | /** Verb for making Request (GET,POST,etc) */
217 | StomtEnumRequestVerb::Type RequestVerb;
218 |
219 | /** Mapping of header section to values. Used to generate final header string for Request */
220 | TMap RequestHeaders;
221 |
222 | /** Cached key/value header pairs. Parsed once Request completes */
223 | TMap ResponseHeaders;
224 |
225 | /** Http Response code */
226 | int32 ResponseCode;
227 |
228 | };
229 |
--------------------------------------------------------------------------------
/Source/StomtPlugin/Public/StomtTrack.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stomt/stomt-unreal-plugin/804051d511c93f424f8b5ea3ed24133109847917/Source/StomtPlugin/Public/StomtTrack.h
--------------------------------------------------------------------------------
/Source/StomtPlugin/StomtPlugin.Build.cs:
--------------------------------------------------------------------------------
1 | // Copyright 2018 STOMT GmbH. All Rights Reserved.
2 |
3 | using UnrealBuildTool;
4 | using System.IO;
5 |
6 | public class StomtPlugin : ModuleRules
7 | {
8 | public StomtPlugin(ReadOnlyTargetRules ROTargetRules) : base(ROTargetRules)
9 | {
10 | PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
11 |
12 | PrivateIncludePaths.AddRange(new string[] { "StomtPlugin/Private" });
13 | PublicIncludePaths.AddRange(new string[] { "StomtPlugin/Public" });
14 |
15 | PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HTTP", "Json", "UMG", "Slate", "SlateCore", "ImageWrapper" });
16 | PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore", "UMG" });
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/StomtPlugin.uplugin:
--------------------------------------------------------------------------------
1 | {
2 | "FileVersion": 3,
3 | "Version": 10,
4 | "VersionName": "2.5.1",
5 | "EngineVersion" : "4.20.0",
6 | "FriendlyName": "StomtPlugin",
7 | "Description": "This Widget allows the easy integration of the feedback solution www.stomt.com in your game.",
8 | "Category": "Widgets",
9 | "CreatedBy": "STOMT",
10 | "CreatedByURL": "https://www.stomt.com",
11 | "DocsURL": "https://github.com/stomt/stomt-unreal-plugin",
12 | "MarketplaceURL" : "com.epicgames.launcher://ue/marketplace/content/7980672d57664bb5a567ff39f5106af6",
13 | "SupportURL": "https://www.stomt.com/stomt-unreal-engine-plugin",
14 | "CanContainContent": true,
15 | "IsBetaVersion": false,
16 | "Installed": false,
17 | "Modules": [
18 | {
19 | "Name": "StomtPlugin",
20 | "Type": "Runtime",
21 | "LoadingPhase": "Default"
22 | }
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/pack.sh:
--------------------------------------------------------------------------------
1 | # RESET
2 | git add .
3 | git stash
4 | git checkout master
5 |
6 |
7 | # next (4.20)
8 | git add .
9 | git stash
10 | git checkout UE/4.20
11 |
12 | # move root files
13 | mv README.md Docs/README.md
14 | mv CONTRIBUTING.md Docs/CONTRIBUTING.md
15 |
16 | # zip
17 | rm ../stomt-unreal-plugin-4-20.zip
18 | zip -r -X ../stomt-unreal-plugin-4-20.zip . -x *.git* -x pack.sh -x scripts/ -x *.DS_Store* -x LICENSE.md -x Binaries/ -x Intermediate/ -x Binaries/**\* -x Intermediate/**\*
19 |
20 |
21 | # next (4.21)
22 | git add .
23 | git stash
24 | git checkout UE/4.21
25 |
26 | # move root files
27 | mv README.md Docs/README.md
28 | mv CONTRIBUTING.md Docs/CONTRIBUTING.md
29 |
30 | # zip
31 | rm ../stomt-unreal-plugin-4-21.zip
32 | zip -r -X ../stomt-unreal-plugin-4-21.zip . -x *.git* -x pack.sh -x scripts/ -x *.DS_Store* -x LICENSE.md -x Binaries/ -x Intermediate/ -x Binaries/**\* -x Intermediate/**\*
33 |
34 |
35 | # next (4.22)
36 | git add .
37 | git stash
38 | git checkout UE/4.22
39 |
40 | # move root files
41 | mv README.md Docs/README.md
42 | mv CONTRIBUTING.md Docs/CONTRIBUTING.md
43 |
44 | # zip
45 | rm ../stomt-unreal-plugin-4-22.zip
46 | zip -r -X ../stomt-unreal-plugin-4-22.zip . -x *.git* -x pack.sh -x scripts/ -x *.DS_Store* -x LICENSE.md -x Binaries/ -x Intermediate/ -x Binaries/**\* -x Intermediate/**\*
47 |
48 |
49 | # next (4.23)
50 | git add .
51 | git stash
52 | git checkout UE/4.23
53 |
54 | # move root files
55 | mv README.md Docs/README.md
56 | mv CONTRIBUTING.md Docs/CONTRIBUTING.md
57 |
58 | # zip
59 | rm ../stomt-unreal-plugin-4-23.zip
60 | zip -r -X ../stomt-unreal-plugin-4-23.zip . -x *.git* -x pack.sh -x scripts/ -x *.DS_Store* -x LICENSE.md -x Binaries/ -x Intermediate/ -x Binaries/**\* -x Intermediate/**\*
61 |
62 |
63 | # next (4.24)
64 | git add .
65 | git stash
66 | git checkout UE/4.24
67 |
68 | # move root files
69 | mv README.md Docs/README.md
70 | mv CONTRIBUTING.md Docs/CONTRIBUTING.md
71 |
72 | # zip
73 | rm ../stomt-unreal-plugin-4-24.zip
74 | zip -r -X ../stomt-unreal-plugin-4-24.zip . -x *.git* -x pack.sh -x scripts/ -x *.DS_Store* -x LICENSE.md -x Binaries/ -x Intermediate/ -x Binaries/**\* -x Intermediate/**\*
75 |
76 |
77 | # next (4.25)
78 | git add .
79 | git stash
80 | git checkout UE/4.25
81 |
82 | # move root files
83 | mv README.md Docs/README.md
84 | mv CONTRIBUTING.md Docs/CONTRIBUTING.md
85 |
86 | # zip
87 | rm ../stomt-unreal-plugin-4-25.zip
88 | zip -r -X ../stomt-unreal-plugin-4-25.zip . -x *.git* -x pack.sh -x scripts/ -x *.DS_Store* -x LICENSE.md -x Binaries/ -x Intermediate/ -x Binaries/**\* -x Intermediate/**\*
89 |
90 |
91 | # next (4.26)
92 | git add .
93 | git stash
94 | git checkout UE/4.26
95 |
96 | # move root files
97 | mv README.md Docs/README.md
98 | mv CONTRIBUTING.md Docs/CONTRIBUTING.md
99 |
100 | # zip
101 | rm ../stomt-unreal-plugin-4-26.zip
102 | zip -r -X ../stomt-unreal-plugin-4-26.zip . -x *.git* -x pack.sh -x scripts/ -x *.DS_Store* -x LICENSE.md -x Binaries/ -x Intermediate/ -x Binaries/**\* -x Intermediate/**\*
103 |
104 |
105 | ## FINSIH
106 | # clean
107 | git add .
108 | git stash
109 | git checkout master
110 |
--------------------------------------------------------------------------------
/scripts/delete_branches.sh:
--------------------------------------------------------------------------------
1 | # RESET
2 | git add .
3 | git stash
4 | git checkout master
5 |
6 |
7 | # remove local braches (to remove changes in them)
8 | git branch -D UE/4.20
9 | git branch -D UE/4.21
10 | git branch -D UE/4.22
11 | git branch -D UE/4.23
12 | git branch -D UE/4.24
13 | git branch -D UE/4.25
14 | git branch -D UE/4.26
15 |
--------------------------------------------------------------------------------
/scripts/push_branches.sh:
--------------------------------------------------------------------------------
1 | # RESET
2 | git add .
3 | git stash
4 | git checkout master
5 |
6 | # push tags
7 | git push --tags
8 |
9 | # push all updates
10 | git push origin master \
11 | UE/4.20 \
12 | UE/4.21 \
13 | UE/4.22 \
14 | UE/4.23 \
15 | UE/4.24 \
16 | UE/4.25 \
17 | UE/4.26 \
18 |
19 |
--------------------------------------------------------------------------------
/scripts/update_branches.sh:
--------------------------------------------------------------------------------
1 | # RESET
2 | git add .
3 | git stash
4 | git checkout master
5 |
6 |
7 | # UE/4.20
8 | git checkout UE/4.20
9 | git merge master
10 |
11 | # UE/4.21
12 | git checkout UE/4.21
13 | git merge master
14 |
15 | # UE/4.22
16 | git checkout UE/4.22
17 | git merge master
18 |
19 | # UE/4.23
20 | git checkout UE/4.23
21 | git merge master
22 |
23 | # UE/4.24
24 | git checkout UE/4.24
25 | git merge master
26 |
27 | # UE/4.25
28 | git checkout UE/4.25
29 | git merge master
30 |
31 | # UE/4.26
32 | git checkout UE/4.26
33 | git merge master
34 |
35 |
36 | ## FINISH
37 | git checkout master
38 |
--------------------------------------------------------------------------------