Commit MetaInfo

Revision3d2c886c31ea2160ea947757541cc7ed1d281805 (tree)
Time2009-08-13 22:36:46
AuthorFace
CommiterFace

Log Message

Added UMmu For Bases.

Change Summary

Incremental Difference

diff -r 12b15ade84f7 -r 3d2c886c31ea Orbitersdk/samples/UMMUFB/UMMUFB.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Orbitersdk/samples/UMMUFB/UMMUFB.cpp Thu Aug 13 15:36:46 2009 +0200
@@ -0,0 +1,270 @@
1+#define STRICT
2+#define ORBITER_MODULE
3+#define DOCKSTRUCTOFFSET_CURRENTDOCKOBJECT 0x48
4+#define ADDRESS_GETDOCKSTATUS 0x004217E0
5+#include <stdio.h>
6+#include "orbitersdk.h"
7+#include "UMMUFB.h"
8+
9+// ==============================================================
10+// Global variables
11+
12+int g_MFDmode; // identifier for new MFD mode
13+DWORD g_Hook;
14+OBJHANDLE g_Transfer;
15+byte g_original[10]={0x8b,0x44,0x24,0x04,0x8b,0x40,0x48,0xc2,0x04,0x00};
16+//The following array is:
17+//_asm
18+//{
19+// pop eax;
20+// push ecx;
21+// push eax;
22+// jmp dword ptr [GetDockStatus]; //Dynamically detected address
23+// nop;
24+//}
25+byte g_code[10] = {0x58, 0x51, 0x50, 0xff, 0x25, 0, 0, 0, 0, 0x90};
26+
27+// ==============================================================
28+// API interface
29+
30+void _stdcall GetLandedPad(VESSEL *vessel, OBJHANDLE &base, DWORD &port)
31+{
32+ VESSELSTATUS2 s;
33+ s.version=2;
34+ s.flag=0;
35+ vessel->GetStatusEx(&s);
36+ base=NULL;
37+ port=0;
38+ if (s.status==1 && s.rbody!=NULL)
39+ {
40+ int k=oapiGetBaseCount(s.rbody);
41+ VECTOR3 distance;
42+ OBJHANDLE nearest=NULL;
43+ double nearestDistance=-1;
44+ for(int i=0;i<k;i++)
45+ {
46+ base=oapiGetBaseByIndex(s.rbody, i);
47+ int l=oapiGetBasePadCount(base);
48+ vessel->GetRelativePos(base, distance);
49+ double len=length(distance);
50+ if (nearestDistance<0 || nearestDistance>len)
51+ {
52+ nearestDistance=len;
53+ nearest=base;
54+ }
55+ }
56+ if (nearest!=NULL)
57+ {
58+ k=oapiGetBasePadCount(nearest);
59+ double vlng, vlat, vrad;
60+ vessel->GetEquPos(vlng, vlat, vrad);
61+ for(int i=0;i<k;i++)
62+ {
63+ double lng, lat;
64+ oapiGetBasePadEquPos(nearest, i, &lng, &lat);
65+ lng-=vlng;
66+ lat-=vlat;
67+ if (sqrt(lng*lng+lat*lat)*vrad<50)
68+ {
69+ port=i+1;
70+ break;
71+ }
72+ }
73+ }
74+ if (port>0) base=nearest;
75+ else base=NULL;
76+ }
77+}
78+
79+OBJHANDLE _stdcall GetDockStatus(VESSEL *vessel, DOCKHANDLE dock)
80+{
81+ //Do my own GetDockStatus
82+ if (g_Transfer!=NULL)
83+ {
84+ OBJHANDLE base;
85+ DWORD port;
86+ GetLandedPad(vessel, base, port);
87+ if (port>0) return g_Transfer;
88+ }
89+ //Original function content
90+ return *(OBJHANDLE *)(void *)((char *)dock+DOCKSTRUCTOFFSET_CURRENTDOCKOBJECT);
91+}
92+
93+int WriteCode(void *address, void *code, DWORD len)
94+{
95+ //Get process information
96+ HANDLE hSelf = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ::GetCurrentProcessId());
97+ MEMORY_BASIC_INFORMATION mbi;
98+
99+ //Open up page of linked address
100+ if(VirtualQueryEx(hSelf, (LPVOID)address, &mbi, sizeof(mbi)) != sizeof(mbi)) return -1;
101+ PVOID pvRgnBaseAddress = mbi.BaseAddress;
102+ DWORD dwOldProtect1, dwOldProtect2, dwFake;
103+ if(!::VirtualProtectEx(hSelf, pvRgnBaseAddress, 4, PAGE_EXECUTE_READWRITE, &dwOldProtect1)) return -2;
104+ BOOL bStridePage = FALSE;
105+ LPBYTE lpByte = (LPBYTE)pvRgnBaseAddress;
106+ lpByte += 4096;
107+ if((DWORD)lpByte < (DWORD)address + 4) bStridePage = TRUE;
108+ PVOID pvRgnBaseAddress2 = (LPVOID)lpByte;
109+ if(bStridePage)
110+ if(!::VirtualProtectEx(hSelf, pvRgnBaseAddress2, 4, PAGE_EXECUTE_READWRITE, &dwOldProtect2))
111+ {
112+ ::VirtualProtectEx(hSelf, pvRgnBaseAddress, 4, dwOldProtect1, &dwFake);
113+ return -3;
114+ }
115+
116+ //Write code
117+ memcpy(address, code, len);
118+
119+ //Lock vtables again
120+ ::VirtualProtectEx(hSelf, pvRgnBaseAddress, 4, dwOldProtect1, &dwFake);
121+ if(bStridePage) ::VirtualProtectEx(hSelf, pvRgnBaseAddress2, 4, dwOldProtect2, &dwFake);
122+}
123+
124+DLLCLBK void InitModule (HINSTANCE hDLL)
125+{
126+ //Hook
127+ union
128+ {
129+ void *pointer;
130+ byte bytes[4];
131+ DWORD value;
132+ } p;
133+ g_Hook=(DWORD)(void *)GetDockStatus;
134+ g_Transfer=NULL;
135+ p.pointer=(void *)&g_Hook;
136+ for(int i=0;i<4;i++) g_code[5+i] = p.bytes[i];
137+ if (memcmp((void *)g_original, (void *)ADDRESS_GETDOCKSTATUS, 10)==0)
138+ WriteCode((void *)ADDRESS_GETDOCKSTATUS, (void *)g_code, 10);
139+
140+ static char *name = "UMMUFB";
141+ MFDMODESPEC spec;
142+ spec.name = name;
143+ spec.key = OAPI_KEY_U;
144+ spec.msgproc = UMMUFB::MsgProc;
145+
146+ // Register the new MFD mode with Orbiter
147+ g_MFDmode = oapiRegisterMFDMode (spec);
148+}
149+
150+DLLCLBK void ExitModule (HINSTANCE hDLL)
151+{
152+ // Unregister the custom MFD mode when the module is unloaded
153+ oapiUnregisterMFDMode (g_MFDmode);
154+
155+ //Unhook
156+ if (memcmp((void *)g_code, (void *)ADDRESS_GETDOCKSTATUS, 10)==0)
157+ WriteCode((void *)ADDRESS_GETDOCKSTATUS, (void *)g_original, 10);
158+}
159+
160+// ==============================================================
161+// MFD class implementation
162+
163+// Constructor
164+UMMUFB::UMMUFB (DWORD w, DWORD h, VESSEL *vessel)
165+: MFD (w, h, vessel)
166+{
167+ this->vessel=vessel;
168+ this->object=vessel->GetHandle();
169+ this->width=(int)w/35;
170+ this->heigth=(int)h/28;
171+}
172+
173+// Destructor
174+UMMUFB::~UMMUFB ()
175+{
176+ // Add MFD cleanup code here
177+}
178+
179+// Return button labels
180+char *UMMUFB::ButtonLabel (int bt)
181+{
182+ // The labels for the two buttons used by our MFD mode
183+ static char *label[2] = {"REL", "TST"};
184+ return (bt < 2 ? label[bt] : 0);
185+}
186+
187+// Return button menus
188+int UMMUFB::ButtonMenu (const MFDBUTTONMENU **menu) const
189+{
190+ // The menu descriptions for the two buttons
191+ static const MFDBUTTONMENU mnu[2] = {
192+ {"Release from parents", 0, 'D'},
193+ {"Test UMMU", 0, 'T'}
194+ };
195+ if (menu) *menu = mnu;
196+ return 2; // return the number of buttons used
197+}
198+
199+// Repaint the MFD
200+void UMMUFB::Update (HDC hDC)
201+{
202+ ATTACHMENTHANDLE point;
203+ DWORD i, j=vessel->AttachmentCount(true);
204+ char buffer[80];
205+ strcpy(buffer, "F R E E");
206+ /*for(i=0;i<j;i++)
207+ {
208+ point=vessel->GetAttachmentHandle(true, i);
209+ if (point!=0)
210+ if (vessel->GetAttachmentStatus(point)!=0)
211+ {
212+ strcpy(buffer, "A T T A C H E D");
213+ break;
214+ }
215+ }*/
216+ DOCKHANDLE port=vessel->GetDockHandle(0);
217+ OBJHANDLE dock=vessel->GetDockStatus(port);//GetDockStatus(vessel, port);
218+ if (dock!=NULL) strcpy(buffer, "D O C K E D");
219+ int l=strlen(buffer);
220+ SelectDefaultFont (hDC, 0);
221+ SelectDefaultPen (hDC, 4);
222+ TextOut(hDC, (35-l)/2*this->width, 13*this->heigth, buffer, l);
223+}
224+
225+// MFD message parser
226+int UMMUFB::MsgProc (UINT msg, UINT mfd, WPARAM wparam, LPARAM lparam)
227+{
228+ switch (msg) {
229+ case OAPI_MSG_MFD_OPENED:
230+ // Our new MFD mode has been selected, so we create the MFD and
231+ // return a pointer to it.
232+ return (int)(new UMMUFB (LOWORD(wparam), HIWORD(wparam), (VESSEL*)lparam));
233+ }
234+ return 0;
235+}
236+
237+bool UMMUFB::ConsumeKeyBuffered(DWORD key)
238+{
239+ switch(key)
240+ {
241+ case OAPI_KEY_D:
242+ return true;
243+ case OAPI_KEY_T:
244+ TestUMMU();
245+ return true;
246+ default:
247+ return false;
248+ }
249+}
250+
251+bool UMMUFB::ConsumeButton(int bt, int event)
252+{
253+ if (event==PANEL_MOUSE_LBPRESSED)
254+ {
255+ switch(bt)
256+ {
257+ case 0:
258+ return ConsumeKeyBuffered(OAPI_KEY_D);
259+ case 1:
260+ return ConsumeKeyBuffered(OAPI_KEY_T);
261+ }
262+ }
263+ return false;
264+}
265+
266+void UMMUFB::TestUMMU()
267+{
268+ g_Transfer=object;
269+ return;
270+}
diff -r 12b15ade84f7 -r 3d2c886c31ea Orbitersdk/samples/UMMUFB/UMMUFB.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Orbitersdk/samples/UMMUFB/UMMUFB.h Thu Aug 13 15:36:46 2009 +0200
@@ -0,0 +1,26 @@
1+#ifndef __UMMUFB_H
2+#define __UMMUFB_H
3+
4+#include "UMmuSDK.h"
5+
6+class UMMUFB: public MFD {
7+public:
8+ UMMUFB (DWORD w, DWORD h, VESSEL *vessel);
9+ ~UMMUFB ();
10+ char *ButtonLabel (int bt);
11+ int ButtonMenu (const MFDBUTTONMENU **menu) const;
12+ bool ConsumeKeyBuffered (DWORD key);
13+ bool ConsumeButton (int bt, int event);
14+ void Update (HDC hDC);
15+ static int MsgProc (UINT msg, UINT mfd, WPARAM wparam, LPARAM lparam);
16+private:
17+ // UMMU 1.5 DECLARATION
18+ UMMUCREWMANAGMENT Crew;
19+ VESSEL *vessel;
20+ OBJHANDLE object;
21+ void TestUMMU();
22+ int width;
23+ int heigth;
24+};
25+
26+#endif // !__UMMUFB_H
\ No newline at end of file
diff -r 12b15ade84f7 -r 3d2c886c31ea Orbitersdk/samples/UMMUFB/UMMUFB.sln
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Orbitersdk/samples/UMMUFB/UMMUFB.sln Thu Aug 13 15:36:46 2009 +0200
@@ -0,0 +1,20 @@
1+
2+Microsoft Visual Studio Solution File, Format Version 9.00
3+# Visual Studio 2005
4+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UMMUFB", "UMMUFB.vcproj", "{D9F1F391-3CA9-4979-84BE-FAF8FAC1F950}"
5+EndProject
6+Global
7+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
8+ Debug|Win32 = Debug|Win32
9+ Release|Win32 = Release|Win32
10+ EndGlobalSection
11+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
12+ {D9F1F391-3CA9-4979-84BE-FAF8FAC1F950}.Debug|Win32.ActiveCfg = Debug|Win32
13+ {D9F1F391-3CA9-4979-84BE-FAF8FAC1F950}.Debug|Win32.Build.0 = Debug|Win32
14+ {D9F1F391-3CA9-4979-84BE-FAF8FAC1F950}.Release|Win32.ActiveCfg = Release|Win32
15+ {D9F1F391-3CA9-4979-84BE-FAF8FAC1F950}.Release|Win32.Build.0 = Release|Win32
16+ EndGlobalSection
17+ GlobalSection(SolutionProperties) = preSolution
18+ HideSolutionNode = FALSE
19+ EndGlobalSection
20+EndGlobal
diff -r 12b15ade84f7 -r 3d2c886c31ea Orbitersdk/samples/UMMUFB/UMMUFB.vcproj
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Orbitersdk/samples/UMMUFB/UMMUFB.vcproj Thu Aug 13 15:36:46 2009 +0200
@@ -0,0 +1,268 @@
1+<?xml version="1.0" encoding="Windows-1252"?>
2+<VisualStudioProject
3+ ProjectType="Visual C++"
4+ Version="8,00"
5+ Name="UMMUFB"
6+ ProjectGUID="{D9F1F391-3CA9-4979-84BE-FAF8FAC1F950}"
7+ RootNamespace="UMMUFB"
8+ >
9+ <Platforms>
10+ <Platform
11+ Name="Win32"
12+ />
13+ </Platforms>
14+ <ToolFiles>
15+ </ToolFiles>
16+ <Configurations>
17+ <Configuration
18+ Name="Debug|Win32"
19+ OutputDirectory=".\Debug"
20+ IntermediateDirectory=".\Debug"
21+ ConfigurationType="2"
22+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
23+ UseOfMFC="0"
24+ ATLMinimizesCRunTimeLibraryUsage="false"
25+ >
26+ <Tool
27+ Name="VCPreBuildEventTool"
28+ />
29+ <Tool
30+ Name="VCCustomBuildTool"
31+ />
32+ <Tool
33+ Name="VCXMLDataGeneratorTool"
34+ />
35+ <Tool
36+ Name="VCWebServiceProxyGeneratorTool"
37+ />
38+ <Tool
39+ Name="VCMIDLTool"
40+ PreprocessorDefinitions="_DEBUG"
41+ MkTypLibCompatible="true"
42+ SuppressStartupBanner="true"
43+ TargetEnvironment="1"
44+ TypeLibraryName=".\Debug/UMMUFB.tlb"
45+ HeaderFileName=""
46+ />
47+ <Tool
48+ Name="VCCLCompilerTool"
49+ Optimization="0"
50+ AdditionalIncludeDirectories="..\..\..\Doc\UMmu_SDK\UMmu_ShuttlePB_Example;..\..\include"
51+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
52+ MinimalRebuild="true"
53+ RuntimeLibrary="3"
54+ PrecompiledHeaderFile=".\Debug/UMMUFB.pch"
55+ AssemblerListingLocation=".\Debug/"
56+ ObjectFile=".\Debug/"
57+ ProgramDataBaseFileName=".\Debug/"
58+ WarningLevel="3"
59+ SuppressStartupBanner="true"
60+ DebugInformationFormat="4"
61+ />
62+ <Tool
63+ Name="VCManagedResourceCompilerTool"
64+ />
65+ <Tool
66+ Name="VCResourceCompilerTool"
67+ PreprocessorDefinitions="_DEBUG"
68+ Culture="2057"
69+ />
70+ <Tool
71+ Name="VCPreLinkEventTool"
72+ />
73+ <Tool
74+ Name="VCLinkerTool"
75+ OutputFile="../../../Modules/Plugin/UMMUFB.dll"
76+ LinkIncremental="2"
77+ SuppressStartupBanner="true"
78+ IgnoreAllDefaultLibraries="false"
79+ IgnoreDefaultLibraryNames="msvcirt.lib;msvcrt.lib"
80+ GenerateDebugInformation="true"
81+ ProgramDatabaseFile=".\Debug/UMMUFB.pdb"
82+ SubSystem="2"
83+ ImportLibrary=".\Debug/UMMUFB.lib"
84+ TargetMachine="1"
85+ />
86+ <Tool
87+ Name="VCALinkTool"
88+ />
89+ <Tool
90+ Name="VCManifestTool"
91+ />
92+ <Tool
93+ Name="VCXDCMakeTool"
94+ />
95+ <Tool
96+ Name="VCBscMakeTool"
97+ SuppressStartupBanner="true"
98+ OutputFile=".\Debug/UMMUFB.bsc"
99+ />
100+ <Tool
101+ Name="VCFxCopTool"
102+ />
103+ <Tool
104+ Name="VCAppVerifierTool"
105+ />
106+ <Tool
107+ Name="VCWebDeploymentTool"
108+ />
109+ <Tool
110+ Name="VCPostBuildEventTool"
111+ />
112+ </Configuration>
113+ <Configuration
114+ Name="Release|Win32"
115+ OutputDirectory=".\Release"
116+ IntermediateDirectory=".\Release"
117+ ConfigurationType="2"
118+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
119+ UseOfMFC="0"
120+ ATLMinimizesCRunTimeLibraryUsage="false"
121+ >
122+ <Tool
123+ Name="VCPreBuildEventTool"
124+ />
125+ <Tool
126+ Name="VCCustomBuildTool"
127+ />
128+ <Tool
129+ Name="VCXMLDataGeneratorTool"
130+ />
131+ <Tool
132+ Name="VCWebServiceProxyGeneratorTool"
133+ />
134+ <Tool
135+ Name="VCMIDLTool"
136+ PreprocessorDefinitions="NDEBUG"
137+ MkTypLibCompatible="true"
138+ SuppressStartupBanner="true"
139+ TargetEnvironment="1"
140+ TypeLibraryName=".\Release/UMMUFB.tlb"
141+ HeaderFileName=""
142+ />
143+ <Tool
144+ Name="VCCLCompilerTool"
145+ Optimization="2"
146+ InlineFunctionExpansion="1"
147+ AdditionalIncludeDirectories="..\..\include"
148+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
149+ StringPooling="true"
150+ RuntimeLibrary="2"
151+ EnableFunctionLevelLinking="true"
152+ PrecompiledHeaderFile=".\Release/UMMUFB.pch"
153+ AssemblerListingLocation=".\Release/"
154+ ObjectFile=".\Release/"
155+ ProgramDataBaseFileName=".\Release/"
156+ BrowseInformation="1"
157+ WarningLevel="3"
158+ SuppressStartupBanner="true"
159+ />
160+ <Tool
161+ Name="VCManagedResourceCompilerTool"
162+ />
163+ <Tool
164+ Name="VCResourceCompilerTool"
165+ PreprocessorDefinitions="NDEBUG"
166+ Culture="2057"
167+ />
168+ <Tool
169+ Name="VCPreLinkEventTool"
170+ />
171+ <Tool
172+ Name="VCLinkerTool"
173+ OutputFile=".\Release/UMMUFB.dll"
174+ LinkIncremental="1"
175+ SuppressStartupBanner="true"
176+ IgnoreDefaultLibraryNames="msvcirt.lib"
177+ ProgramDatabaseFile=".\Release/UMMUFB.pdb"
178+ SubSystem="2"
179+ ImportLibrary=".\Release/UMMUFB.lib"
180+ TargetMachine="1"
181+ />
182+ <Tool
183+ Name="VCALinkTool"
184+ />
185+ <Tool
186+ Name="VCManifestTool"
187+ />
188+ <Tool
189+ Name="VCXDCMakeTool"
190+ />
191+ <Tool
192+ Name="VCBscMakeTool"
193+ SuppressStartupBanner="true"
194+ OutputFile=".\Release/UMMUFB.bsc"
195+ />
196+ <Tool
197+ Name="VCFxCopTool"
198+ />
199+ <Tool
200+ Name="VCAppVerifierTool"
201+ />
202+ <Tool
203+ Name="VCWebDeploymentTool"
204+ />
205+ <Tool
206+ Name="VCPostBuildEventTool"
207+ Description="Installing binaries"
208+ CommandLine="move Release\*.dll ..\..\..\Modules\Plugin"
209+ />
210+ </Configuration>
211+ </Configurations>
212+ <References>
213+ </References>
214+ <Files>
215+ <Filter
216+ Name="SDK"
217+ >
218+ <File
219+ RelativePath="..\..\lib\orbiter.lib"
220+ >
221+ </File>
222+ <File
223+ RelativePath="..\..\include\Orbitersdk.h"
224+ >
225+ </File>
226+ <File
227+ RelativePath="..\..\lib\Orbitersdk.lib"
228+ >
229+ </File>
230+ <File
231+ RelativePath="..\..\..\Doc\UMmu_SDK\UMmu_ShuttlePB_Example\UMmuSDK.h"
232+ >
233+ </File>
234+ <File
235+ RelativePath="..\..\..\Doc\UMmu_SDK\UMmu_ShuttlePB_Example\UMmuSDK.lib"
236+ >
237+ </File>
238+ </Filter>
239+ <File
240+ RelativePath="UMMUFB.cpp"
241+ >
242+ <FileConfiguration
243+ Name="Debug|Win32"
244+ >
245+ <Tool
246+ Name="VCCLCompilerTool"
247+ AdditionalIncludeDirectories=""
248+ PreprocessorDefinitions=""
249+ />
250+ </FileConfiguration>
251+ <FileConfiguration
252+ Name="Release|Win32"
253+ >
254+ <Tool
255+ Name="VCCLCompilerTool"
256+ AdditionalIncludeDirectories=""
257+ PreprocessorDefinitions=""
258+ />
259+ </FileConfiguration>
260+ </File>
261+ <File
262+ RelativePath="UMMUFB.h"
263+ >
264+ </File>
265+ </Files>
266+ <Globals>
267+ </Globals>
268+</VisualStudioProject>
diff -r 12b15ade84f7 -r 3d2c886c31ea Orbitersdk/samples/UMMUFB/copyright
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Orbitersdk/samples/UMMUFB/copyright Thu Aug 13 15:36:46 2009 +0200
@@ -0,0 +1,7 @@
1+Copyright (c) 2009 Friedrich Kastner-Masilko, M.Sc.
2+
3+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:
4+
5+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6+
7+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.
\ No newline at end of file
Show on old repository browser